【问题标题】:MappedbyteBuffer.get() increments position by too muchMappedbyteBuffer.get() 将位置增加太多
【发布时间】: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


【解决方案1】:

原来我是个大白痴。我没有注意到字节 82 0a 96 仅在右侧重复了几个字节。这是我不小心放置缓冲区位置的地方。别担心,我很惭愧。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多