2017-03-16 56 views
0

尝试使用RandomAcessFile读取和写入同一文件时出现问题。写入字节块后的文件更改权限

我正在从一个文件读取16个字节的块,并将它们写入给定位置(例如256个)的同一个文件中。

问题出在ra.write(b)一行。当下面一行是执行我上了文本编辑器凯特消息(我使用Linux Manjaro)说:

文件/home/mite/IdeaProjects/IspitJuni2015/dat.txt与打开UTF-8编码但包含无效字符。 它被设置为只读模式,因为保存可能会破坏其内容。 可以选择正确的编码重新打开文件,也可以在工具菜单中再次启用读写模式以编辑它。

它打开只读模式。 另外我尝试手动取消在凯特只读权限,但它也不工作。什么似乎是问题?

public static byte[] read(long i) throws IOException{ 
    File in = new File("./dat.txt"); 
    RandomAccessFile ra = new RandomAccessFile(in,"rw"); 
    byte[] readObj= new byte[16]; 
    if (i>in.length()/16) 
    { 
     return null; 
    } 
    ra.seek(i*16); 
    ra.read(readObj); 
    ra.close(); 
    return readObj; 
} 
public static void write(long i, byte[] obj) throws IOException{ 
    File out=new File("./dat.txt"); 
    RandomAccessFile ra=new RandomAccessFile(out,"rw"); 
    if (!out.exists()) 
    { 
     out.createNewFile(); 
    } 
    long size=out.length(); 
    if (i*16>size) 
    { 
     ra.seek(out.length()); 
     for (long j=size;j<i*16;j+=16) 
     { 
      byte[] b=new byte[16]; 
      ra.write(b); 
     } 
    } 
    ra.seek((i)*16); 
    System.out.println(new String(obj)); 
    ra.write(obj); 
    ra.close(); 
} 
public static void main(String[] args) throws IOException{ 
    write(35,read(4)); 
} 
+1

'out.exists()/ createNewFile()'块在最好情况下毫无意义,但尤其如此*在构建了'RandomAccessFile'之后。去掉它。 – EJP

+0

Hi Mitko。答案已在下面提出,你是否能够回复它,并回答它是否帮助你? – halfer

+1

@halfer嗨,我留下重播和可能的解决方案。你可以看下面的 –

回答

1

我想你误解了你的编辑告诉你的。

首先,并非每个可能的字节序列都是有效的UTF-8字符串,请参阅"UTF-8 decoder capability and stress test"。因此,当您将16个字节从UTF-8文件的一个位置复制到另一个位置时,您可能会收到一个不再包含有效UTF-8文本的文件。

我怀疑你在凯特打开了相同的文件来查看你的编辑结果。编辑对你说的是,它注意到你打开的文件不是一个有效的UTF-8文件,因此它不知道如何正确处理它,从而防止意外损坏你潜在的宝贵数据,现在看起来像二进制(不是文本)到编辑器,编辑器拒绝将任何内容从UI保存回该文件。这不会更改文件系统级别的任何权限,可能其他(dumber)编辑器不会警告您这种可能的损坏。

0

谢谢你的回复。我解决了这个问题。

有时候文本编辑器在文件末尾增加一个额外的字节,在Java中不支持该字节。通常这是EOF字节,并被视为UTF-8,其中Java只接受写入/读取ASCI字节,但通过writeUTF()方法进行操作除外。

此字节在文本编辑器中是不可见的,这就是我写这篇文章的原因。

花了我两天的时间才发现问题所在,但如果有人被卡在这里,请记住EOF字节。