2016-10-02 119 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