【问题标题】:RandomAccesFile and UTF8 lineRandomAccessFile 和 UTF 8 行
【发布时间】:2016-08-28 14:51:46
【问题描述】:

我使用 RandomAccessFile 对象来读取 UTF-8 法语文件。我使用readLine 方法。

下面是我的 Groovy 代码:

while ((line = randomAccess.readLine())) {
    def utfLine = new String(line.getBytes('UTF-8'), 'UTF-8')
    ++count
    long nextRecordPos = randomAccess.getFilePointer()

    compareNextRecords(utfLine, randomAccess)

    randomAccess.seek(nextRecordPos)
}

我的问题是 utfLineline 是一样的:重音字符保持像 é 而不是 é。未完成任何转换。

【问题讨论】:

  • 不要使用 RandomAccessFile 读取字符。使用 BufferedReader,由 InputStreamReader 构造并指定正确的编码,本身由 FileInputStream 构造。
  • 你能说明randomAccess是如何构造的吗?
  • @JBNizet 抱歉,我需要对我的文件使用随机访问权限。
  • @Tunaki 我使用 def randomAccess = new RandomAccessFile(f, 'r') 创建实例

标签: java groovy utf-8 randomaccessfile


【解决方案1】:

首先,这行代码完全没有任何作用。数据是一样的。删除它:

def utfLine = new String(line.getBytes('UTF-8'), 'UTF-8')

根据 Javadoc,RandomAccessFile.readLine() 不知道字符编码。它读取字节,直到遇到“\r”或“\n”或“\r\n”。 ASCII 字节值以正常方式放入返回的字符串中。但是 128 到 255 之间的字节值会按字面意义放入字符串中,而不会将其解释为字符编码(或者您可以说这是原始/逐字编码)。

RandomAccessFile 中没有设置字符编码的方法或构造函数。但是使用readLine() 仍然很有价值,因为它负责解析换行符序列并分配内存。

在您的情况下,最简单的解决方案是通过反转 readLine() 所做的手动将假“行”转换为字节,然后将字节解码为具有字符编码意识的真实字符串。不知道怎么用Groovy写代码,就用Java来回答吧:

String fakeLine = randomAccess.readLine();
byte[] bytes = new byte[fakeLine.length()];
for (int i = 0; i < fakeLine.length(); i++)
    bytes[i] = (byte)fakeLine.charAt(i);
String realLine = new String(bytes, "UTF-8");

【讨论】:

  • 我试过:def utfLine = new String(line.getBytes(), 'UTF-8') 但结果是一样的。
  • 您的解决方案有效 :) 但是,为什么它有效,而不是 line.getBytes() 的调用?
  • 因为getBytes()会将128-255范围内的值转义为不同的字节序列
  • 这很疯狂而且不直观。感谢四位您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-09
  • 2017-05-07
  • 1970-01-01
  • 1970-01-01
  • 2011-10-11
  • 2017-05-19
  • 2015-12-03
相关资源
最近更新 更多