0

pcapファイルを読み取るために独自のクラスを実装しました。(バイナリファイル、つまりtcpdump、wireshark)

public class PcapReader implements Iterator<PcapPacket> {
    private InputStream is;

    public PcapReader (File file) throws FileNotFoundException, IOException {
        is = this(new DataInputStream(
             new BufferedInputStream(
                 new FileInputStream(file))));
    }

    @Override
    public boolean hasNext () {
        try {
            return (is.available() > 0);
        } catch (IOException e) {
            return false;
        }
    }

    //pseudo code!
    @Override
    public PcapPacket next () {
        is.read(header);
        is.read(body);

        return new PcapPacket(header, body);
    }

    //more code here
}

それから私はそれをこのように使います:

PcapReader reader = new PcapReader(file);
while (reader.hasNext()) {
    PcapPacket pcapPacket = reader.next();
    //process packet
}

テスト対象のファイルの容量は190Mbです。また、JVisualVMを使用してプロファイルを作成します。

  • hasNext()は170万回呼び出され、時間は7.7秒です

  • next()同じ回数呼び出され、時間は3.6秒です

私の主な質問は、なぜhasNext()絶対値でこれほど時間がかかり、またその2倍の時間がかかるのnextかということです。

4

3 に答える 3

2

メソッドでを呼び出すとis.available()、実装になります。FileInputStreamソースコードからわかるように、これはネイティブメソッドです。hasNext()FileInputStream.available()

結局のところ、これは確かに時間のかかる操作です。ファイル操作のオペレーティングシステムの実装では、さらに多くのデータを読み取ることができるかどうかを事前に確認する必要があるためです。したがって、実際には、ファイルポインタを更新せずに(または元の位置に更新して戻すことなく)、「次の」バイトがあるかどうかを確認するだけで、読み取り操作を実行します。

于 2013-03-06T14:22:21.820 に答える
1

確かに、available()メソッドの内部(ネイティブ)実装は、単にいくつかを返すようなものではなくreturn availableSize;、より複雑です。ストリームは、OSAPIを使用して利用可能なデータをカウントします。特に、たとえば、Streamが読み取るために書き込まれるログファイルの場合。

于 2013-03-06T14:23:01.043 に答える
1

pcapファイルを読み取るために独自のクラスを実装しました。

jNetPcapを使用していないため、またはjNetPcapFile使用しているが、 ?から読み取ることができるものが必要なため

後者の場合は、「より多くのデータが利用可能」メソッドと別の「そのデータを読み取る」メソッドを持つパターン以外のパターンを使用することをお勧めします。データを読み取り、「パケット使用可能」/「ファイルの終わり」/「エラー」表示を返すか、後者の条件の一方または両方に対して例外をスローするもの(DataInputStreamI / OエラーとEOFの両方に対して例外をスローするように見える)したがって、クラスでも同じことを行うのが理にかなっている場合があります)。

ええ、それはそれがであってはならないことを意味しますIterator、しかし多分Iteratorsはもともとシーケンシャルファイルのレコードを表すことを意図していませんでした(それ以外に、本当にそれをしたいのなら、あなたIteratorはメソッドについて何をするつもりremoveですか?)。

また、から読み取る必要がない場合はFile、jNetPcap独自のルーチンを使用してキャプチャファイルを読み取ることができます。これは、libpcap 1.1.0以降では、一部のpcap-ngファイルも読み取ることができます。

于 2013-03-07T01:31:16.010 に答える