Java 俄罗斯字符
最近我开始学习java.nio。在我的教科书中,我有一个例子,如何使用seekablebytechnel阅读文本文件:Java 俄罗斯字符,java,encoding,java-7,nio,cyrillic,Java,Encoding,Java 7,Nio,Cyrillic,最近我开始学习java.nio。在我的教科书中,我有一个例子,如何使用seekablebytechnel阅读文本文件: int count; Path path; try { path = Paths.get(System.getProperty("user.home") + "/desktop/text.txt"); } catch (InvalidPathException e) { out.println(e.getMessage()); return; } t
int count;
Path path;
try {
path = Paths.get(System.getProperty("user.home") + "/desktop/text.txt");
} catch (InvalidPathException e) {
out.println(e.getMessage());
return;
}
try (SeekableByteChannel channel = Files.newByteChannel(path)) {
ByteBuffer buffer = ByteBuffer.allocate(128);
do {
count = channel.read(buffer);
if (count != -1) {
buffer.rewind();
for (int i = 0; i < count; i++)
out.print((char) buffer.get());
}
} while (count != -1);
} catch (IOException e) {
out.println("File not found!!!");
}
out.flush();
int计数;
路径;
试一试{
path=path.get(System.getProperty(“user.home”)+“/desktop/text.txt”);
}捕获(无效的异常e){
out.println(e.getMessage());
返回;
}
try(seekableytechnel=Files.newbytechnel(路径)){
ByteBuffer缓冲区=ByteBuffer.allocate(128);
做{
计数=通道读取(缓冲区);
如果(计数!=-1){
buffer.rewind();
for(int i=0;i
所以我用ANSI编码制作了一个包含英语和俄语单词的文本文件。这就是我得到的:
方法buffer.get()返回字节值,俄语字符从1000开始。因此,我将编码更改为UTF-8,并使用了另一种方法:
for (int i = 0; i < count; i += 2)
out.print(buffer.getChar()); //reads 2 bytes and converts them to char
for(int i=0;i
但这给了我一个问号
那么,有人知道如何使用seekablebytechnel正确阅读俄语文本吗?ByteBuffer的方法getChar()
读取两个字节,并将它们解释为字符的高字节和低字节,换句话说,总是使用UTF-16
编码。通常,您不应该尝试手动将字节拼凑到String
s,而不是使用旧的I/O API和NIO。请注意,在尝试手动解码缓冲区中的字节时,需要处理的一件事是,对于多字节编码,缓冲区中的字节可能不会以字符边界结束
如果要从seekablebytechnel
读取文本,可以使用来构造读取器
,使用指定的字符集对字节进行解码
当然,您可以完全跳过频道
的内容,并使用从路径
创建一个阅读器
顺便说一下,示例代码是有问题的,即使是读取字节序列。以下是一个简化的示例:
Path path=Paths.get(System.getProperty("user.home")).resolve("desktop/text.txt");
try(FileChannel channel=FileChannel.open(path)) {
ByteBuffer buffer = ByteBuffer.allocate(128);
while(channel.read(buffer)!=-1) {
buffer.flip();
while(buffer.hasRemaining())
System.out.printf("%02x ", buffer.get());
buffer.clear();
System.out.println();
}
} catch (IOException e) {
System.out.println(e.toString());
}
一个ByteBuffer
知道它包含多少字节(即通过读取操作已放入其中)。使用flip
可以准备缓冲区,以便读取它们,例如使用示例中的循环或写入另一个通道。当您知道您已经处理了全部内容时,可以使用清除
将缓冲区设置为初始状态,从开始到结束都可以填充
否则,如果它可能包含未处理的数据,请改用compact
,这会将未处理的数据移动到缓冲区的开头,并准备在它们之后接收更多数据,因此,在后续的read
和flip
之后,您就有了上一次迭代的挂起数据,然后是最近的读取操作的数据,可以作为单个序列进行处理。(这就是阅读器在解码时内部处理不完整字符序列的方式)text.txt可以更好地用于示例。