Johnyzhub
Johnyzhub

Reputation: 414

MappedByteBuffer writing to file not working

I am having hard time understanding the read write with MappedByteBuffer. Here is the class I have that reads the content of a local file and suppose to reverse its content. I am using java version 8.

public class MappedByteBufferExample {
public static void main(String[] args) {
    try (RandomAccessFile file = new RandomAccessFile("resources\\MappedByteBufferExample.txt", "rw");
            FileChannel fileChannel = file.getChannel();) {
        long size = fileChannel.size();
        MappedByteBuffer mappedBuffer = fileChannel.map(MapMode.READ_WRITE, 0, size);

        System.out.println("Text from File : -----");
        while (mappedBuffer.remaining() > 0) {
            System.out.print((char) mappedBuffer.get());
        }
        System.out.println("\n");

        for (int index = 0; index < (mappedBuffer.limit() / 2); index++) {
            byte b1 = mappedBuffer.get(index);
            byte b2 = mappedBuffer.get(mappedBuffer.limit() - index - 1);
            mappedBuffer.put(index, b2);
            mappedBuffer.put(mappedBuffer.limit() - index - 1, b1);
        }
        //mappedBuffer.force();  I tried with this but no change in result.
        //mappedBuffer.load(); I tried with this but no change in result.
        mappedBuffer.load();
        mappedBuffer.flip();
        System.out.println("Text Reversed : -----");
        while (mappedBuffer.remaining() > 0) {
            System.out.print((char) mappedBuffer.get());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}}

The content of the file is - Roses are Red!
On executing this file output to the console is:

Text from File : -----

Roses are Red!

Text Reversed : -----

!deR era sesoR

But the content of the file is unchanged. On executing this program on second time, the output to the console is:

Text from File : -----

!deR era sesoR

Text Reversed : -----

Roses are Red!

The content of the file is still unchanged. I tried load() and force() methods one at a time and both, but no change in the result Here are my questions:

1) Why the content of the local file is not changed?

2) What changes does this program need to make the data to be written to the file?

3) Why/How the MappedByteBuffer has read reversed text on second iteration, though the file content is not reversed?

Upvotes: 0

Views: 1155

Answers (2)

Holger
Holger

Reputation: 298233

Since you’re actual problem has been solved, some remarks:

  • Since Java 1.7, you don’t need the RandomAccessFile detour to open a FileChannel
  • The Charset API allows you to convert a ByteBuffer’s content to characters correctly (casting byte to char is only correct for a subset of the, e.g. current Windows code page) and without the need to iterate over the bytes manually
  • The swapping loop can be written straightforwardly by using two indices rather than recalculating the second index (and the loop’s end index) in each iteration

Putting these points together, the simplified variant looks like:

try(FileChannel fileChannel = FileChannel.open(
        Paths.get("resources\\MappedByteBufferExample.txt"),
        StandardOpenOption.READ, StandardOpenOption.WRITE)) {
    long size = fileChannel.size();
    MappedByteBuffer mappedBuffer = fileChannel.map(MapMode.READ_WRITE, 0, size);

    System.out.println("Text from File : -----");
    System.out.append(Charset.defaultCharset().decode(mappedBuffer)).println("\n");

    for(int index1 = 0, index2=(int)size-1; index1<index2; index1++, index2--) {
        byte b1 = mappedBuffer.get(index1), b2 = mappedBuffer.get(index2);
        mappedBuffer.put(index1, b2).put(index2, b1);
    }
    mappedBuffer.force();
    mappedBuffer.flip();
    System.out.println("Text Reversed : -----");
    System.out.append(Charset.defaultCharset().decode(mappedBuffer)).println("\n");
} catch (IOException e) {
    e.printStackTrace();
}

Keep in mind that the reading loop will always show the altered state, regardless of whether it has been written to the file. So whether force() is placed before the reading loop or at the end of the block doesn’t matter.

Upvotes: 0

Heri
Heri

Reputation: 4588

The content of the file IS changed. Usual editors (like notepad++ or eclipse) do not remark the change because the file datetime is not changed by using RandomAccessFile. But if you really reload the file manually after the run you should see the changes.

Upvotes: 3

Related Questions