【发布时间】:2017-04-06 11:59:57
【问题描述】:
我的文件的相关部分是这样的:
82 0a 96 c9 82 0a 96 d3 00 66 13 08
我在映射字节缓冲区中打开文件并将位置设置为开头。然后我这样做:
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
...
buffer.position(packetInfos.get(idPacket).getStartPos());
//getting the time from the packet header
time = Math.addExact(Math.multiplyExact((long) buffer.order(ByteOrder.LITTLE_ENDIAN).getInt(), 1000), Math.floorDiv(buffer.order(ByteOrder.LITTLE_ENDIAN).getInt(), 1000));
//getting the source ip from the ip frame
buffer.position(packetInfos.get(idPacket).getStartPos() + PACKET_IPSOURCE_OFFS); // puts the buffers position at the part of the file shown above
source = byteToUnsigned(buffer.get()) + "." + byteToUnsigned(buffer.get()) + "." + byteToUnsigned(buffer.get()) + "." + byteToUnsigned(buffer.get());
//getting the destination ip from the ip frame
destination = byteToUnsigned(buffer.get()) + "." + byteToUnsigned(buffer.get()) + "." + byteToUnsigned(buffer.get()) + "." + byteToUnsigned(buffer.get());
byteToUnsigned 方法很简单:
public static int byteToUnsigned(byte b){
return b & 0xFF;
}
源最终是:“130.10.150.211”,而它应该是“130.10.150.201”。 由于某种原因,get() 方法在大多数情况下将缓冲区的位置增加 1,但在第三次之后增加 5?正如您可能已经猜到的那样,我试图在之后解码目标 ip,它在“D3”之后开始读取,导致“0.102.19.8”
即使在 byteToUnsigned 调用之前,源 Ip 也是“-126.10.-106.-45”。
通过这一行一步步调试后:
source = byteToUnsigned(buffer.get()) + "." + byteToUnsigned(buffer.get()) + "." + byteToUnsigned(buffer.get()) + "." + byteToUnsigned(buffer.get());
观察 buffer.position() 和 buffer.get(),我可以看到以下内容:
- 第一次get():buffer.position()=70,buffer.get()=-126
- 第二次get():buffer.position()=71,buffer.get()=10
- 第三个get():buffer.position()=72, buffer.get()=-106
- 第四次get():buffer.position()=73,buffer.get()=-45
所以位置是正确递增的,但是第 72 和第 77 之间的字节不知何故对缓冲区不可见?
Api 明确指出:
public abstract byte get()
Relative get method. Reads the byte at this buffer's current position, and then increments the position.
我错过了什么?
【问题讨论】:
-
好吧,要么 Java 中存在严重错误,要么您有其他代码执行了移动位置的操作。
-
我会在哪里做呢?两个 get() 调用之间没有额外的代码。此外,缓冲区是在该函数中创建的,并且可以重现确切的错误。
-
不保证 SO。这个问题的问题在于它说
get()移动位置超过1字节(你知道这不是真的)。现在,由于MappedByteBuffer中不太可能存在错误,因此最可能的原因是您的代码中存在错误。人们在问题中编写的代码与他们实际运行的代码不同 也并非闻所未闻(出于某种原因,他们避免复制粘贴),因此人们会浪费时间尝试调试错误的代码。我建议在调试器中逐步进行,如果您可以验证错误,请提交错误报告。 -
是的,我只是在解释这里的数千个问题是如何得到“处理”的。你有重复(我如何比较字符串),坏学生(这是我的家庭作业),人们试图咬得比他们能咀嚼的更多(我想要创建一个 MMORPG),然后你得到了许多简单的错误可以通过粗略的一瞥来解决,有时您会遇到更高级/有趣的问题,因为它们很有趣而受到关注。然后你有那些从缝隙中掉下来并且没有被关闭或回答的问题,比如这个。这与个人无关。
-
我认为最可能的解释是这段代码:
buffer.position(packetInfos.get(idPacket).getStartPos() + PACKET_IPSOURCE_OFFS);没有将缓冲区定位在您认为的位置,您只是在读取第二个 IP 地址而不是第一个。请注意,两者的前三个字节完全相同。
标签: java increment memory-mapped-files mappedbytebuffer