主要:

package main;

import racreader.RAFReader;

public class RandomAccessFile {

    public static void main(String[] args) {
        if (args.length != 2) {
            System.err.println("Wrong arguments length");
            System.exit(1);
        }
        try {
            RAFReader reader = new RAFReader (args[0]);
            try {

                String output = reader.readUTF(Integer.parseInt(args[1]));
                System.out.print(output);
            } catch (Exception e) {
                System.err.println(e.toString());
            } finally {
                reader.close();
            }
        } catch (Exception e) {
            System.err.println(e.toString());
        }
    }
}


RAFReader:

package racreader;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RAFReader {

    private final String fileName;
    private final RandomAccessFile reader;

    public RAFReader(String fileName) throws FileNotFoundException {
        this.fileName = fileName;
        this.reader = openFile();

    }

    private RandomAccessFile openFile() throws FileNotFoundException {
        RandomAccessFile reader = new RandomAccessFile(fileName, "r");
        return reader;
    }

    public String readUTF(int offset) throws IOException {
        reader.seek(offset);
        String output = reader.readUTF();
        return output;
    }

    public void close() throws IOException {
        reader.close();
    }
}


问题出在每个文件(甚至以UTF8编码)和每个偏移量的EOFException中。为什么?

UPD:我尝试让我的程序使用具有以下内容的文件:

Это тест UTF-8 чтения


仅当offset = 0时,它才能正常工作。任何其他偏移量都会引发EOFException。

最佳答案

readUTF()中的writeUTF() / RandomAccesFile方法使用约定来编写Java String对象,而UTF编码的文本文件不一定遵循这些约定。 readUTF()不能用于读取任意文本文件,该文件最初不是使用RandomAccesFile.writeUTF()编写的。

如Javadocs指定的方法,readUTF()假定它读取的前两个字节包含以下字符串中的字节数。如果通过配对writeUTF()方法将字符串写入文件,就是这种情况,但是在文本文件的情况下,这将抛出间歇性的EOFException,因为前两个字节将包含字符串中的实际字符。

在您的情况下,一组不同的类可以解决问题。考虑使用RAFReader重写InputStreamReader类:

public String readUTF(int offset) throws IOException {
    FileInputStream is = new FileInputStream(fileName);

    Reader fileReader = new InputStreamReader(is, "UTF-8");
    StringBuilder stringBuilder = new StringBuilder();

    fileReader.skip(offset);

    int charsRead;
    char buf[] = new char[256];

    //Read until there is no more characters to read.
    while ((charsRead = fileReader.read(buf)) > 0) {
        stringBuilder.append(buf, 0, charsRead);
    }

    fileReader.close();

    return stringBuilder.toString();
}


如果必须使用RandomAccesFile,则可以使用包装RandomAccesFile的输入流。最简单的方法是通过RandomAccesFile封装的FileChannel:

InputStream is = Channels.newInputStream(reader.getChannel());

关于java - Java的RandomAccessFIle EOFException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21980090/

10-10 03:38