0

RandomAccessFile 的默认实现是“损坏的”,因为您无法指定文件的编码方式。

我正在寻找符合以下条件的替代方案:

  1. 编码感知
  2. 随机访问!(处理非常大的文件,需要能够使用字节偏移量定位光标而不流式传输整个内容)。

我在 Commons IO 中闲逛了一下,但那里什么都没有。我宁愿不必自己实现这一点,因为有太多地方可能出错。

4

2 回答 2

1

RandomAccessFile 用于访问二进制数据。不可能有效地创建适用于所有情况的随机访问编码文件。

即使您找到了这样的解决方案,我也会仔细检查以确保它适合您的需求。

如果您要编写它,我建议您考虑行和列的随机位置,而不是从文件开头的字符偏移量。

这样做的好处是您只需要记住每行的开头在哪里,您就可以扫描该行以获取您的角色。如果你索引每个字符的位置,这可以为每个字符使用 4 个字节(假设文件小于 4 GB)

于 2013-04-25T07:17:13.820 回答
0

事实证明,答案没有我想象的那么痛苦:

// This gives me access to buffering and charset magic
new BufferedReader(new InputStreamReader(Channels.newInputStream(randomAccessFile.getChannel()), encoding)), encoding
....

然后我可以实现一个逐字符读取的 readLine() 方法。使用 String.getBytes(encoding) 我可以跟踪文件中的偏移量。在底层 RandomAccessFile 上调用 seek() 可以让我随意重新定位光标。那里可能潜伏着一些错误,但基本测试似乎有效。

public String readLine() throws IOException {
    eol = "";
    lastLineByteCount = 0;
    StringBuilder builder = new StringBuilder();

    char[] characters = new char[1];
    int status = reader.read(characters, 0, 1);

    if (status == -1) {
        return null;
    }

    char c = characters[0];
    while (status != -1) {
        if (c == '\n') {
            eol += c;
            break;
        }

        if (c == '\r') {
            eol += c;
        } else {
            builder.append(c);
        }

        status = reader.read(characters, 0, 1);
        c = characters[0];
    }

    String line = builder.toString();

    lastLineByteCount = line.getBytes(encoding).length + eol.getBytes(encoding).length;

    return line;
}
于 2013-04-25T09:15:50.237 回答