2016-10-02 121 views
-1

我很難理解用MappedByteBuffer讀寫。 這裏是我讀取本地文件的內容,並假設其內容顛倒的類。我正在使用java版本8.MappedByteBuffer寫入文件不起作用

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()和力()方法之一的時間和雙方,但在結果 這裏沒有改變是我的問題:

1)爲什麼本地文件的內容沒有改變?

2)該程序需要將數據寫入文件中需要做什麼修改?

3)爲什麼/如何在第二次迭代中MappedByteBuffer讀取反轉的文本,但文件內容沒有反轉?

+0

不需要加載和翻轉。 println只需要「flip」,因爲它會重置讀取位置。但是隻有在最後纔會寫回文本(在這種情況下)。 「\ r \ n」將變成「\ n \ r」。 –

+0

你沒有提供證據表明該文件沒有被更改,並且是一個主要的證據。 – EJP

回答

2

文件內容發生變化。通常的編輯器(如notepad ++或eclipse)不會標註更改,因爲使用RandomAccessFile不會更改文件日期時間。但是如果你真的在運行後手動重新加載文件,你應該看到更改。

+0

謝謝@Heri。我被Notepad ++愚弄了。它沒有重新加載內容。你的評論節省了我的時間。 – JohnySam

0

既然你實際的問題已經解決,一些言論:

  • 由於Java 1.7,你不需要RandomAccessFile迂迴打開一個FileChannel
  • Charset API允許你轉換ByteBuffer的內容與字符正確(鑄造bytechar只對正確的一個子集,例如當前的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()是否放置在讀取循環之前或塊的結尾並不重要。

+0

感謝您分享您的有用評論,Holger。 – JohnySam