尝试使用RandomAcessFile读取和写入同一文件时遇到问题。
我正在从一个文件中读取16个字节的块,并将它们写在给定位置的同一个文件中(例如256个)。
问题出在ra.write(b)
行。当执行以下行时,我在文本编辑器Kate(我正在使用Linux Manjaro)上收到一条消息:
文件/home/mite/IdeaProjects/IspitJuni2015/dat.txt以UTF-8编码打开但包含无效字符。 它被设置为只读模式,因为保存可能会破坏其内容。 使用所选的正确编码重新打开文件,或在工具菜单中再次启用读写模式,以便能够对其进行编辑。
并打开只读模式。 此外,我尝试手动取消选中Kate中的只读权限,但它也无法正常工作。什么似乎是问题?
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));
}
答案 0 :(得分:1)
我认为你误解了你的编辑告诉你的内容。
首先,并非每个可能的字节序列都是有效的UTF-8字符串,例如参见"UTF-8 decoder capability and stress test"。因此,当您从UTF-8文件的一个位置复制16个字节到另一个位置时,您可能会得到一个不再包含有效UTF-8文本的文件。
我怀疑您在Kate中打开了相同的文件,以查看您的修改结果。编辑们对你说的是,它注意到你打开的文件不是有效的UTF-8文件,因此它不知道如何正确处理它,从而防止意外损坏你现在看起来像的宝贵数据编辑器的二进制(不是文本),编辑器拒绝将任何内容从UI保存回该文件。这不会更改文件系统级别的任何权限,并且其他(dumber)编辑可能不会就此类可能的损坏向您发出警告。
答案 1 :(得分:0)
感谢您的回复。我发现了问题。
有时文本编辑器会在文件末尾添加一个额外字节,而Java中不支持该字节。通常这是EOF
字节,并被视为UTF-8,Java只接受写入/读取ASCI字节,除了通过writeUTF()
方法进行操作。
此字节在文本编辑器中也是不可见的,这就是我写这篇文章的原因。
我花了两天时间才找出问题所在,但如果有人卡在这里,请记住EOF字节。