JLine 的编码问题
Encoding issue with JLine
Jline 是一个模块,用于在用户按下 Enter
之前在控制台拦截用户输入。它使用 JNA 或类似的魔法。
我正在用它做一些实验,当我输入更多 "exotic" Unicode 字符时遇到编码问题。这里的 OS 是 W10,我使用的是 Cygwin。这也在 Groovy 中,但对 Java 人来说应该是显而易见的。
def terminal = org.jline.terminal.TerminalBuilder.builder().jna( true ).system( true ).build()
terminal.enterRawMode()
// NB the Terminal I get is class org.jline.terminal.impl.PosixSysTerminal
def reader = terminal.reader()
def bytes = [] // NB class ArrayList
int readInt = -1
while( readInt != 13 && readInt != 10 ) {
readInt = reader.read()
byte convertedByte = (byte)readInt
// see what the binary looks like:
String binaryString = String.format("%8s", Integer.toBinaryString( convertedByte & 0xFF)).replace(' ', '0')
println "binary |$binaryString|"
bytes << (byte)readInt // NB means "append to list"
println ">>> read |$readInt| byte |$convertedByte|"
}
// strip final byte (13 or 10)
bytes = bytes[0..-2]
println "z bytes $bytes, class ${bytes.class.name}"
def response = new String( (byte[])bytes.toArray(), 'UTF-8' )
// to get proper out encoding for Cygwin I then need to do this (I have no idea why!)
def psOut = new PrintStream(System.out, true, 'UTF-8' )
psOut.print( "using PrintStream: |$response|" )
这适用于单字节 Unicode,并且可以很好地处理像“é”(2 字节)这样的字母。但是“ẃ”就出错了:
ẃ --> Unicode U+1E83
UTF-8 HEX: 0xE1 0xBA 0x83 (e1ba83)
BINARY: 11100001:10111010:10000011
实际上当你输入“ẃ”时它输出的二进制文件是11100001:10111010:10010010.
这转换为 U+1E92,这是另一个波兰字符“Ẓ”。这确实是 response
String
.
中打印出来的内容
不幸的是,JLine 包给了你这个 reader
,它是 class org.jline.utils.NonBlocking$NonBlockingInputStreamReader
...所以我真的不知道我能做些什么来调查它的编码(我假定为 UTF-8) 或以某种方式对其进行修改...谁能解释问题出在哪里?
据我所知,这与 Cygwin 特有的问题有关,如所问,然后 一年前。
在 中有一个解决方案,针对我在这个问题之后直接问的问题...它正确处理 Unicode 输入,即使在 Basic Multilingual Plane 之外,使用 JLine,...和使用 Cygwin 控制台...希望如此。
Jline 是一个模块,用于在用户按下 Enter
之前在控制台拦截用户输入。它使用 JNA 或类似的魔法。
我正在用它做一些实验,当我输入更多 "exotic" Unicode 字符时遇到编码问题。这里的 OS 是 W10,我使用的是 Cygwin。这也在 Groovy 中,但对 Java 人来说应该是显而易见的。
def terminal = org.jline.terminal.TerminalBuilder.builder().jna( true ).system( true ).build()
terminal.enterRawMode()
// NB the Terminal I get is class org.jline.terminal.impl.PosixSysTerminal
def reader = terminal.reader()
def bytes = [] // NB class ArrayList
int readInt = -1
while( readInt != 13 && readInt != 10 ) {
readInt = reader.read()
byte convertedByte = (byte)readInt
// see what the binary looks like:
String binaryString = String.format("%8s", Integer.toBinaryString( convertedByte & 0xFF)).replace(' ', '0')
println "binary |$binaryString|"
bytes << (byte)readInt // NB means "append to list"
println ">>> read |$readInt| byte |$convertedByte|"
}
// strip final byte (13 or 10)
bytes = bytes[0..-2]
println "z bytes $bytes, class ${bytes.class.name}"
def response = new String( (byte[])bytes.toArray(), 'UTF-8' )
// to get proper out encoding for Cygwin I then need to do this (I have no idea why!)
def psOut = new PrintStream(System.out, true, 'UTF-8' )
psOut.print( "using PrintStream: |$response|" )
这适用于单字节 Unicode,并且可以很好地处理像“é”(2 字节)这样的字母。但是“ẃ”就出错了:
ẃ --> Unicode U+1E83
UTF-8 HEX: 0xE1 0xBA 0x83 (e1ba83)
BINARY: 11100001:10111010:10000011
实际上当你输入“ẃ”时它输出的二进制文件是11100001:10111010:10010010.
这转换为 U+1E92,这是另一个波兰字符“Ẓ”。这确实是 response
String
.
不幸的是,JLine 包给了你这个 reader
,它是 class org.jline.utils.NonBlocking$NonBlockingInputStreamReader
...所以我真的不知道我能做些什么来调查它的编码(我假定为 UTF-8) 或以某种方式对其进行修改...谁能解释问题出在哪里?
据我所知,这与 Cygwin 特有的问题有关,如所问,然后
在