1

我正在尝试读取编码为 UTF-16 文件的(日语)文件。

当我使用带有“UTF-16”字符集的 InputStreamReader 读取它时,文件被正确读取:

try {
        InputStreamReader read = new InputStreamReader(new FileInputStream("JapanTest.txt"), "UTF-16");
        BufferedReader in = new BufferedReader(read);
        String str;
        while((str=in.readLine())!=null){           
            System.out.println(str);
    }
    in.close();
}catch (Exception e){
    System.out.println(e);
}

但是,当我使用文件通道并从字节数组中读取时,字符串并不总是正确转换:

    File f = new File("JapanTest.txt");
    fis = new FileInputStream(f);
    channel = fis.getChannel();
     MappedByteBuffer buffer = channel.map( FileChannel.MapMode.READ_ONLY, 0L, channel.size());
     buffer.position(0);
    int get = Math.min(buffer.remaining(), 1024);
    byte[] barray = new byte[1024];
    buffer.get(barray, 0, get);
    CharSet charSet = Charset.forName("UTF-16");
    //endOfLinePos is a calculated value and defines the number of bytes to read
    rowString = new String(barray, 0, endOfLinePos, charSet);               
    System.out.println(rowString);

我发现的问题是,如果 MappedByteBuffer 位于位置 0,我只能正确读取字符。如果我增加 MappedByteBuffer 的位置,然后将多个字节读入字节数组,然后使用转换为字符串字符集 UTF-16,则字节未正确转换。如果文件以 UTF-8 编码,我还没有遇到过这个问题,那么这只是 UTF-16 的问题吗?

更多详细信息:我需要能够从文件通道中读取任何行,因此我构建了一个行结束字节位置列表,然后使用这些位置来获取任何给定行的字节,然后转换它们到一个字符串。

4

2 回答 2

1

UTF-16 的编码单元是 2 个字节,而不是像 UTF-8 那样一个字节。模式和单字节码单元长度使UTF-8自同步;它可以在任何时候正确读取,如果它是一个连续字节,它可以回溯或只丢失一个字符。

使用 UTF-16,您必须始终使用字节对,您不能从奇数字节开始读取或在奇数字节处停止读取。您还必须知道字节顺序,并且在文件开头不读取时使用 UTF-16LE 或 UTF-16BE,因为不会有 BOM。

您还可以将文件编码为 UTF-8。

于 2012-12-18T10:33:55.957 回答
1

可能,InputStreamReader正常情况下不会进行一些转换new String(...)。作为一种解决方法(并验证此假设),您可以尝试包装从通道读取的数据,例如new InputStreamReader( new ByteArrayInputStream( barray ) ).

编辑:忘记:) - Channels.newReader()将是要走的路。

于 2012-12-18T06:29:23.897 回答