我正在实现一个像这样工作的软件:
我有一个 Linux 服务器运行一个输出文本的 vt100 终端应用程序。 我的程序远程登录服务器并将文本位读取/解析为相关数据。 相关数据被发送到由网络服务器运行的小型客户端,该客户端在 HTML 页面上输出数据。
我的问题是某些特殊字符如“åäö”被输出为问号(经典)。
背景:
我的程序使用 Apache Commons TelnetClient 读取字节流。字节流被转换成一个字符串,然后相关位被子字符串化并与分隔符放回一起。在此之后,新字符串被转换回字节数组并使用 Socket 发送到由网络服务器运行的客户端。该客户端根据接收到的字节创建一个字符串,并将其打印在标准输出上,网络服务器从中读取并输出 HTML。
第 1 步: byte[] --> String --> byte[] --> [发送给客户端]
第二步: byte[] --> 字符串 --> [打印输出]
问题:
当我在 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();
webserver运行的客户端:
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”中的默认字符集似乎让特殊字符一路通过服务器到网络服务器,但在 Linux 计算机上运行时默认字符集是不同的。我尝试运行“Charset.defaultCharset().forName()”,它显示我的 Linux 计算机设置为“US-ASCII”。我以为 Linux 默认为“UTF-8”?
我应该怎么做才能让我的程序在 Linux 上运行?
最佳答案
依赖平台默认编码通常不是一个好主意,尤其是网络通信协议(protocol)。
new String()
和 String.getBytes()
都被重载以允许您指定编码。由于您控制编码和解码,因此只需使用 UTF-8(硬编码)。
还要检查您的代码是否使用了 FileInputStream
、FileOutputStream
、InputStreamReader
和 OutputStreamWriter
,所有这些都可能依赖于平台默认编码(前两个,唯一的,这使得它们非常无用)。
关于Java byte to String Linux 上的编码问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7025568/