Проблема кодирования с JLine
Jline - это модуль для перехвата пользовательского ввода на консоли, прежде чем пользователь нажмет Enter
, Это использует JNA или подобное волшебство.
Я провожу несколько экспериментов с ним, и у меня возникают проблемы с кодированием, когда я вводлю более "экзотические" символы Юникода. ОС здесь 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|" )
Это прекрасно работает с однобайтовым Юникодом, и такие письма, как "é" (2 байта), обрабатываются нормально. Но это не так с "goes":
ẃ --> Unicode U+1E83
UTF-8 HEX: 0xE1 0xBA 0x83 (e1ba83)
BINARY: 11100001:10111010:10000011
На самом деле двоичный файл, который он выводит при вводе "ẃ", равен 11100001: 10111010:10010010.
Это переводит к U+1E92, который является другим польским символом, "Ẓ". И это действительно то, что распечатывается в response
String
,
К сожалению, пакет JLine вручает вам это reader
, который является классом org.jline.utils.NonBlocking$NonBlockingInputStreamReader
... Так что я действительно не знаю, что я могу сделать, чтобы исследовать его кодировку (я предполагаю UTF-8) или как-то изменить его... Может кто-нибудь объяснить, в чем проблема?
1 ответ
Насколько я могу судить, это относится к специфической для Cygwin проблеме, на которую я спросил, а затем ответил год назад.
В моем ответе на вопрос, который я задал сразу после этого, есть решение, которое правильно относится к вводу Unicode, даже когда он находится за пределами базовой многоязычной плоскости, с использованием JLine, ... и с использованием консоли Cygwin... надеюсь,