Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux上的Java字节到字符串编码问题_Java_Linux_Character Encoding_Apache Commons - Fatal编程技术网

Linux上的Java字节到字符串编码问题

Linux上的Java字节到字符串编码问题,java,linux,character-encoding,apache-commons,Java,Linux,Character Encoding,Apache Commons,我正在实现一个软件,其工作原理如下: 我有一个Linux服务器,运行输出文本的vt100终端应用程序。 我的程序对服务器进行远程登录,并将文本的位读取/解析为相关数据。 相关数据被发送到由Web服务器运行的小型客户机,该服务器在HTML页面上输出数据 我的问题是像“åäö”这样的特殊字符被输出为问号(经典) 背景: 我的程序使用Apache Commons TelnetClient读取字节流。字节流被转换成一个字符串,然后相关的位被子字符串化,并用分隔符重新组合。在此之后,新字符串被转换回字节数

我正在实现一个软件,其工作原理如下:

我有一个Linux服务器,运行输出文本的vt100终端应用程序。 我的程序对服务器进行远程登录,并将文本的位读取/解析为相关数据。 相关数据被发送到由Web服务器运行的小型客户机,该服务器在HTML页面上输出数据

我的问题是像“åäö”这样的特殊字符被输出为问号(经典)

背景:
我的程序使用Apache Commons TelnetClient读取字节流。字节流被转换成一个字符串,然后相关的位被子字符串化,并用分隔符重新组合。在此之后,新字符串被转换回字节数组,并使用套接字发送到Web服务器运行的客户端。该客户端从接收到的字节创建一个字符串,并在标准输出上打印出来,Web服务器从标准输出读取和输出HTML

步骤1: 字节[]-->字符串-->字节[]-->[发送到客户端]

步骤2: 字节[]-->字符串-->[打印输出]

问题:
当我在Windows上运行Java程序时,所有字符(包括“åäö”)都会正确输出到生成的HTML页面上。但是,如果我在Linux上运行该程序,所有特殊字符都将转换为“”(问号)

Web服务器和客户端当前正在Windows上运行(步骤2)

代码:
程序基本上是这样工作的:

我的节目:

byte[] data = telnetClient.readData() // Assume method works and returns a byte[] array of text.

// I have my reasons to append the characters one at a time using a StringBuffer.
StringBuffer buf = new StringBuffer();
for (byte b : data) {
    buf.append((char) (b & 0xFF));
}

String text = buf.toString();

// ...
// Relevant bits are substring'ed and put back into the String.
// ...

ServerSocket serverSocket = new ServerSocket(...);
Socket socket = serverSocket.accept();
serverSocket.close();

socket.getOutputStream.write(text.getBytes());
socket.getOutputStream.flush();
Web服务器运行的客户端:

Socket socket = new Socket(...);

byte[] data = readData(socket); // Assume this reads the bytes correctly.

String output = new String(data);

System.out.println(output);
假设读写之间的同步工作正常

想法:
我尝试了不同的编码和解码字节数组的方法,但没有结果。我对字符集编码问题有点陌生,希望得到一些建议。Windows“Windows 1252”中的默认字符集似乎允许特殊字符从服务器一直到Web服务器,但在Linux计算机上运行时,默认字符集是不同的。我尝试运行一个“Charset.defaultCharset().forName()”,它显示我的Linux计算机被设置为“US-ASCII”。我以为Linux默认为“UTF-8”


如何让程序在Linux上运行?

通常,依赖平台默认编码是个坏主意,尤其是对于网络通信协议

newstring()
String.getBytes()
都被重载,以允许您指定编码。因为您可以控制编码和解码,所以只需使用UTF-8(硬编码)


还要检查您的代码是否使用了
FileInputStream
FileOutputStream
InputStreamReader
OutputStreamWriter
,所有这些都依赖于平台默认编码(前两个是专用的,这使得它们非常无用).

依赖平台默认编码通常是个坏主意,尤其是对于网络通信协议

newstring()
String.getBytes()
都被重载,以允许您指定编码。因为您可以控制编码和解码,所以只需使用UTF-8(硬编码)

还要检查您的代码是否使用了
FileInputStream
FileOutputStream
InputStreamReader
OutputStreamWriter
,所有这些都可能依赖于平台默认编码(前两个是专用的,这使得它们非常无用)。

String(byte[]bytes,String编码)
是你的朋友。只需将所有原始字节读入字节缓冲区,并使用此构造函数将字节解码为Java字符串。(或:转码为UTF-16,内部字符编码)

方法
getBytes(字符串编码)
将字符串编码为字节。

String(byte[]字节,字符串编码)
是您的朋友。只需将所有原始字节读入字节缓冲区,并使用此构造函数将字节解码为Java字符串。(或:转码为UTF-16,内部字符编码)


方法
getBytes(字符串编码)
将字符串编码为字节。

关键细节是从
telnetClient.readData()返回的数据的编码是什么?听起来像是
windows-1252
。考虑到这一点,你有两个选择。您可以将所有
字符串
操作的编码显式设置为
windows-1252

text.getBytes("windows-1252");

String output = new String(data, "windows-1252");

或者,您可以使用
java.nio.charset.charset
将telnet数据转换为不太特定于平台的数据,如
UTF-8
,如下示例:--仍然显式设置
字符串
操作中的字符集。

关键细节是从
telnetClient.readData()
?听起来像是
windows-1252
。考虑到这一点,你有两个选择。您可以将所有
字符串
操作的编码显式设置为
windows-1252

text.getBytes("windows-1252");

String output = new String(data, "windows-1252");

或者,您可以使用
java.nio.charset.charset
将telnet数据转换为不太特定于平台的数据,如
UTF-8
,如下示例:--仍然明确设置
String
操作中的字符集。

如何使用StringBuffer进行解码<代码>buf.append(新字符串(新字节[]{b},“UTF-8”))
?但是,否则我应该在整个程序(包括客户端)中始终使用UTF-8进行解码和编码?@snipes83:删除StringBuffer。这是一个毫无意义的、容易出错的复杂问题,并且需要更复杂的逻辑才能为UTF-8工作,因为它将对ASCII之外的字符使用多个字节。或者解释你想这样做的原因,我们可能会找到更好的解决方案来实现你真正想要的。否则,可以在任何地方使用UTF-8。避免在两者之间转换