1

I'm experimenting with Mapped Byte Buffer (Java), I have to use DirectBuffer on a file to perform some arithmetic operations:

MappedByteBuffer mbf = new RandomAccessFile("blah.bin", "rw").getChannel().map(FileChannel.MapMode.READ_WRITE,0,100*8L);

Questions: - is the direct buffer is zeroed filled? I have a debug method which dumps the values as

    private void dump(){
    for (int i = 0; i < 100; i++) {
        System.out.println(mbf.getDouble(i));
    }
}

Interestingly, when I take take the dump before writing any values, it's dumping all zeroes (doubles):

When I write to any location say:

mbf.putDouble(13,100.0);

When I re-ran the dump, it's dumping some random values:

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

My logic is dependent on the zero value

if (mbf.getDouble(6)==0.0)
//then do some thing
else
//do some thing else

How can I ensure the values are properly initialized to zero before writing any condition like above? Does any one got a similar issue? what's the best way to tackle this situation?

Any insights are highly appreciated.

Few more details: OS: Windows 10 JDK: java version "1.8.0_111"

Thanks in advance!

humblecoder
  • 499
  • 2
  • 5
  • 15

2 Answers2

1

A double value occupies 8 bytes. (In Java always, in some other languages usually but not always.) From the 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.

When you ask for the double starting at byte index 6, it actually uses bytes 6 through 13, and byte 13 contains the first byte of the (nonzero) value you stored.

dave_thompson_085
  • 34,712
  • 6
  • 50
  • 70
  • Thanks @dave, for pin pointing the index, I really messed them up, but now fixed by multiplying by 8 (size of double). – humblecoder Mar 08 '18 at 15:24
1

Is the direct buffer is zeroed filled?

I tend to believe it is zero filled. Because as I use the below code to open blah.bin file, the size on the disk is 800 bytes on both Windows and linux.

When I re-ran the dump, it's dumping some random values:

You are seeing the random values because you are not moving the position of the mapped byte buffer correctly. i.e., Integer takes 4 bytes, so once you are done with reading it at index 0 you should start you next integer at position 3. Similarly for double it is 8 bytes.

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());

    }   
}

Hope this helps.