Java 映射字节缓冲区 - 缓冲区中的垃圾值
Java Mapped Byte Buffer - garbage values in buffer
我正在试验映射字节缓冲区 (Java),我必须在文件上使用 DirectBuffer 来执行一些算术运算:
MappedByteBuffer mbf = new RandomAccessFile("blah.bin", "rw").getChannel().map(FileChannel.MapMode.READ_WRITE,0,100*8L);
问题:
- 直接缓冲区是否已清零填充?
我有一个调试方法将值转储为
private void dump(){
for (int i = 0; i < 100; i++) {
System.out.println(mbf.getDouble(i));
}
}
有趣的是,当我在写入任何值之前进行转储时,它会转储所有零(双精度):
当我写到任何位置时说:
mbf.putDouble(13,100.0);
当我重新运行 转储时,它转储了一些 运行dom 值:
0.0
0.0
0.0
0.0
0.0
3.16E-322
8.1387E-320
2.0835183E-317
5.333806864E-315
1.36545455721E-312
3.4955636664571E-310
1.8187371284868433E-307
100.0
5.164499756173817E120
0.0
0.0
0.0
0.0
0.0
我的逻辑依赖于零值
if (mbf.getDouble(6)==0.0)
//then do some thing
else
//do some thing else
如何确保在写入上述任何条件之前将值正确初始化为零?有没有人有类似的问题?解决这种情况的最佳方法是什么?
非常感谢任何见解。
更多细节:
OS: Windows 10
JDK: java 版本“1.8.0_111”
提前致谢!
一个double
值占用8个字节。 (在 Java 中总是,在一些其他语言中通常但不总是。)来自 javadoc https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html#getDouble-int-
Reads eight bytes at the given index, composing them into a double value according to the current byte order.
当您要求从字节索引 6 开始的 double 时,它实际上使用字节 6 到 13,而字节 13 包含您存储的(非零)值的第一个字节。
Is the direct buffer is zeroed filled?
我倾向于认为它是零填充的。因为当我使用下面的代码打开 blah.bin 文件时,磁盘上的大小在 Windows 和 linux.
上都是 800 字节
When I re-ran the dump, it's dumping some random values:
您看到的是随机值,因为您没有正确移动 mapped byte buffer
的 position
。即,Integer 需要 4 个字节,所以一旦你在索引 0 处读取完它,你应该从位置 3 开始你的下一个整数。同样对于 double 它是 8 个字节。
package com.test;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class MappedFileGarbage {
public static void main(String[] args) throws Exception {
RandomAccessFile raf = new RandomAccessFile("blah.bin", "rw");
MappedByteBuffer mbf = raf.getChannel().map(FileChannel.MapMode.READ_WRITE,0,100*8L);
mbf.putInt(1000).putInt(2000).putDouble(4000.0);
raf.close();
raf = new RandomAccessFile("blah.bin", "rw");
mbf = raf.getChannel().map(FileChannel.MapMode.READ_WRITE,0,100*8L);
dump(mbf);
}
private static void dump(MappedByteBuffer mbf){
// Reading the data without manually setting the position, as getXXX(n) methods internally increment the position.
System.out.println(mbf.getInt(0));
System.out.println(mbf.getInt(4));
System.out.println(mbf.getDouble(8));
// Reading the data via getXXX() method as manually setting the position, as getXXX(n) methods don't increment the position.
System.out.println(mbf.position());
System.out.println(mbf.getInt());
System.out.println(mbf.position(4));
System.out.println(mbf.getInt());
System.out.println(mbf.position(8));
System.out.println(mbf.getDouble());
System.out.println(mbf.position());
}
}
希望对您有所帮助。
我正在试验映射字节缓冲区 (Java),我必须在文件上使用 DirectBuffer 来执行一些算术运算:
MappedByteBuffer mbf = new RandomAccessFile("blah.bin", "rw").getChannel().map(FileChannel.MapMode.READ_WRITE,0,100*8L);
问题: - 直接缓冲区是否已清零填充? 我有一个调试方法将值转储为
private void dump(){
for (int i = 0; i < 100; i++) {
System.out.println(mbf.getDouble(i));
}
}
有趣的是,当我在写入任何值之前进行转储时,它会转储所有零(双精度):
当我写到任何位置时说:
mbf.putDouble(13,100.0);
当我重新运行 转储时,它转储了一些 运行dom 值:
0.0
0.0
0.0
0.0
0.0
3.16E-322
8.1387E-320
2.0835183E-317
5.333806864E-315
1.36545455721E-312
3.4955636664571E-310
1.8187371284868433E-307
100.0
5.164499756173817E120
0.0
0.0
0.0
0.0
0.0
我的逻辑依赖于零值
if (mbf.getDouble(6)==0.0)
//then do some thing
else
//do some thing else
如何确保在写入上述任何条件之前将值正确初始化为零?有没有人有类似的问题?解决这种情况的最佳方法是什么?
非常感谢任何见解。
更多细节: OS: Windows 10 JDK: java 版本“1.8.0_111”
提前致谢!
一个double
值占用8个字节。 (在 Java 中总是,在一些其他语言中通常但不总是。)来自 javadoc https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html#getDouble-int-
Reads eight bytes at the given index, composing them into a double value according to the current byte order.
当您要求从字节索引 6 开始的 double 时,它实际上使用字节 6 到 13,而字节 13 包含您存储的(非零)值的第一个字节。
Is the direct buffer is zeroed filled?
我倾向于认为它是零填充的。因为当我使用下面的代码打开 blah.bin 文件时,磁盘上的大小在 Windows 和 linux.
上都是 800 字节When I re-ran the dump, it's dumping some random values:
您看到的是随机值,因为您没有正确移动 mapped byte buffer
的 position
。即,Integer 需要 4 个字节,所以一旦你在索引 0 处读取完它,你应该从位置 3 开始你的下一个整数。同样对于 double 它是 8 个字节。
package com.test;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class MappedFileGarbage {
public static void main(String[] args) throws Exception {
RandomAccessFile raf = new RandomAccessFile("blah.bin", "rw");
MappedByteBuffer mbf = raf.getChannel().map(FileChannel.MapMode.READ_WRITE,0,100*8L);
mbf.putInt(1000).putInt(2000).putDouble(4000.0);
raf.close();
raf = new RandomAccessFile("blah.bin", "rw");
mbf = raf.getChannel().map(FileChannel.MapMode.READ_WRITE,0,100*8L);
dump(mbf);
}
private static void dump(MappedByteBuffer mbf){
// Reading the data without manually setting the position, as getXXX(n) methods internally increment the position.
System.out.println(mbf.getInt(0));
System.out.println(mbf.getInt(4));
System.out.println(mbf.getDouble(8));
// Reading the data via getXXX() method as manually setting the position, as getXXX(n) methods don't increment the position.
System.out.println(mbf.position());
System.out.println(mbf.getInt());
System.out.println(mbf.position(4));
System.out.println(mbf.getInt());
System.out.println(mbf.position(8));
System.out.println(mbf.getDouble());
System.out.println(mbf.position());
}
}
希望对您有所帮助。