我已经实现了自己的类来读取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
}
被测文件有190 Mb。我还使用JVisualVM进行配置。
hasNext()
被称为170万次,时间 7.7 秒
next()
被调用的次数相同,时间 3.6 秒
我的主要问题是为什么hasNext()
绝对值非常耗时,而且比next
大两倍?
答案 0 :(得分:2)
当您致电is.available()
时,在hasNext()
方法中,它会逐步实施FileInputStream.available()
。这是一种原生方法,可以从FileInputStream source code看到。
最后,这确实是一个耗时的操作,因为如果有更多数据可供读取,文件操作的操作系统实现必须提前检查。因此,它实际上会在不更新文件指针(或将其更新回原始位置)的情况下执行读取操作,只是为了检查是否存在“下一个”字节。
答案 1 :(得分:1)
我敢肯定,available()
方法的内部(本机)实现不类似于返回一些return availableSize;
,但更复杂。流使用OS API计算可用数据;特别是,例如,对于日志文件,由Stream读取它们。
答案 2 :(得分:1)
我已经实现了自己的类来阅读
pcap
个文件。
因为您没有使用jNetPcap,或者 使用jNetPcap,但需要可以从File
读取的内容?
如果是后者,你可能想要使用一个模式而不是一个具有“更多数据可用”方法的模式和一个单独的“如此读取数据”方法;读取数据的东西,或者返回“可用数据包”/“文件结束”/“错误”指示,或者为后面的一个或两个条件抛出异常(DataInputStream
似乎会抛出I /的异常O错误和EOF,所以为你的班级做同样的事情可能是有道理的。)
是的,这意味着它不能是Iterator
,但也许Iterator
最初并不打算代表顺序文件中的记录(此外,如果你真的希望它是一个Iterator
,您打算如何处理remove
方法?)。
如果你可以避免需要从File
读取,那么你可以使用jNetPcap自己的例程来读取捕获文件,在libpcap 1.1.0及更高版本中,它也可以读取一些pcap-ng文件。