写入块

时间:2017-03-16 21:06:38

标签: java utf-8 readonly randomaccessfile

尝试使用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));
}

2 个答案:

答案 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字节。