簡體   English   中英

MappedByteBuffer寫入文件不起作用

[英]MappedByteBuffer writing to file not working

我很難理解MappedByteBuffer的讀寫。 這是我擁有的用於讀取本地文件內容並假定反轉其內容的類。 我正在使用Java版本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();
    }
}}

該文件的內容是-玫瑰是紅色的!
執行此文件時,輸出到控制台的是:

文件中的文本:-----

玫瑰是紅色的!

文字反轉:-----

!deR時代sesoR

但是文件的內容不變。 第二次執行該程序時,控制台的輸出為:

文件中的文本:-----

!deR時代sesoR

文字反轉:-----

玫瑰是紅色的!

該文件的內容仍保持不變。 我一次嘗試了load()和force()方法,並且一次都嘗試了兩次,但是結果沒有變化。這是我的問題:

1)為什么本地文件的內容沒有改變?

2)該程序需要進行哪些更改才能將數據寫入文件?

3)為什么/如何在不重復文件內容的情況下,MappedByteBuffer在第二次迭代中讀取了反向文本?

文件內容已更改。 通常的編輯器(如notepad ++或eclipse)不會標記更改,因為使用RandomAccessFile不會更改文件日期時間。 但是,如果您確實在運行后手動重新加載文件,則應該會看到更改。

既然您的實際問題已經解決,請注意以下幾點:

  • 從Java 1.7開始,您無需使用RandomAccessFile繞道即可打開FileChannel
  • 使用Charset API,您可以將ByteBuffer的內容正確地轉換為字符(將byte廣播到char僅對於一部分子集(例如當前的Windows代碼頁)是正確的),而無需手動遍歷字節
  • 可以通過使用兩個索引來直接編寫交換循環,而不用在每次迭代中重新計算第二個索引(和循環的結束索引)

將這些要點放在一起,簡化的變體如下所示:

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

請記住,無論是否已將其寫入文件,讀取循環將始終顯示更改后的狀態。 因此,將force()放置在讀取循環之前還是在代碼塊末尾都沒有關系。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM