我目前正在尝试运行需要接收带有法语字符的消息的套接字服务器,例如“àéèîï”等。
所以,这是交易:当我在eclipse中执行我的套接字服务器时,我收到的消息具有正确的编码,因为我可以在控制台中看到重音符号。但是当我将套接字服务器导出到一个可运行的jar文件并在命令提示符下执行时,我收到的消息的编码似乎是错误的。
我知道有很多关于这个问题的帖子,但没有一个解决方案对我有用,或者我可能遗漏了一些东西。
这是一些代码: 对于我的套接字服务器:
server = new SocketServer(port, SocketServer.ASCIIINPUT) {
@Override
public void processMessage(String message, Socket sender) throws MessageException {
try{
System.out.println("Message without decoding : " + message);
System.out.println("Message with UTF-8 decoding : " + URLDecoder.decode(message, "UTF-8"));
System.out.println("Message with ISO-8859-1 decoding : " + URLDecoder.decode(message, "ISO-8859-1"));
} catch(Exception ex){
ex.printStackTrace();
}
}
@Override
public void socketIterationDone() {}
};
我不会发布我的SocketServer的代码,因为它很长但它基本上只是管理连接并使用InputStreamReader实现BufferedReader,以便能够读取收到的消息,如下所示:
final BufferedReader reader = new BufferedReader(new InputStreamReader(in, Charset.forName("UTF-8")));
我也尝试过没有指定Charset:
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
这是我的套接字客户端:
try {
Socket s = new Socket("127.0.0.1", 6005);
s.getOutputStream().write("With UTF-8 encoding: éèï\n".getBytes(Charset.forName("UTF-8")));
s.getOutputStream().write("With ISO-8859-1 encoding: éèï\n".getBytes(Charset.forName("ISO-8859-1")));
s.getOutputStream().write("Without encoding: éèï".getBytes());
s.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
这就是代码。现在,当我在SocketServer类中指定Charset UTF-8时,在命令提示符中有我的结果:
C:\Users\nx_vostro_1\Desktop>java -jar test.jar
Server listening on port: 6005
Message without decoding : With UTF-8 encoding: ÚÞ´
Message with UTF-8 decoding : With UTF-8 encoding: ÚÞ´
Message with ISO-8859-1 decoding : With UTF-8 encoding: ÚÞ´
Message without decoding : With ISO-8859-1 encoding: ???
Message with UTF-8 decoding : With ISO-8859-1 encoding: ???
Message with ISO-8859-1 decoding : With ISO-8859-1 encoding: ???
Message without decoding : Without encoding: ??
Message with UTF-8 decoding : Without encoding: ??
Message with ISO-8859-1 decoding : Without encoding: ??
C:\Users\nx_vostro_1\Desktop>java -Dfile.encoding=UTF-8 -jar test.jar
Server listening on port: 6005
Message without decoding : With UTF-8 encoding: ├®├¿├»
Message with UTF-8 decoding : With UTF-8 encoding: ├®├¿├»
Message with ISO-8859-1 decoding : With UTF-8 encoding: ├®├¿├»
Message without decoding : With ISO-8859-1 encoding: ´┐¢´┐¢´┐¢
Message with UTF-8 decoding : With ISO-8859-1 encoding: ´┐¢´┐¢´┐¢
Message with ISO-8859-1 decoding : With ISO-8859-1 encoding: ´┐¢´┐¢´┐¢
Message without decoding : Without encoding: ´┐¢´┐¢
Message with UTF-8 decoding : Without encoding: ´┐¢´┐¢
Message with ISO-8859-1 decoding : Without encoding: ´┐¢´┐¢
C:\Users\nx_vostro_1\Desktop>java -Dfile.encoding=ISO-8859-1 -jar test.jar
Server listening on port: 6005
Message without decoding : With UTF-8 encoding: ÚÞ´
Message with UTF-8 decoding : With UTF-8 encoding: ÚÞ´
Message with ISO-8859-1 decoding : With UTF-8 encoding: ÚÞ´
Message without decoding : With ISO-8859-1 encoding: ???
Message with UTF-8 decoding : With ISO-8859-1 encoding: ???
Message with ISO-8859-1 decoding : With ISO-8859-1 encoding: ???
Message without decoding : Without encoding: ??
Message with UTF-8 decoding : Without encoding: ??
Message with ISO-8859-1 decoding : Without encoding: ??
现在我没有在SocketServer类中指定Charset:
C:\Users\nx_vostro_1\Desktop>java -jar test.jar
Server listening on port: 6005
Message without decoding : With UTF-8 encoding: ├®├¿├»
Message with UTF-8 decoding : With UTF-8 encoding: ├®├¿├»
Message with ISO-8859-1 decoding : With UTF-8 encoding: ├®├¿├»
Message without decoding : With ISO-8859-1 encoding: ÚÞ´
Message with UTF-8 decoding : With ISO-8859-1 encoding: ÚÞ´
Message with ISO-8859-1 decoding : With ISO-8859-1 encoding: ÚÞ´
Message without decoding : Without encoding: ÚÞ´
Message with UTF-8 decoding : Without encoding: ÚÞ´
Message with ISO-8859-1 decoding : Without encoding: ÚÞ´
C:\Users\nx_vostro_1\Desktop>java -Dfile.encoding=UTF-8 -jar test.jar
Server listening on port: 6005
Message without decoding : With UTF-8 encoding: ├®├¿├»
Message with UTF-8 decoding : With UTF-8 encoding: ├®├¿├»
Message with ISO-8859-1 decoding : With UTF-8 encoding: ├®├¿├»
Message without decoding : With ISO-8859-1 encoding: ´┐¢´┐¢´┐¢
Message with UTF-8 decoding : With ISO-8859-1 encoding: ´┐¢´┐¢´┐¢
Message with ISO-8859-1 decoding : With ISO-8859-1 encoding: ´┐¢´┐¢´┐¢
Message without decoding : Without encoding: ´┐¢´┐¢
Message with UTF-8 decoding : Without encoding: ´┐¢´┐¢
Message with ISO-8859-1 decoding : Without encoding: ´┐¢´┐¢
C:\Users\nx_vostro_1\Desktop>java -Dfile.encoding=ISO-8859-1 -jar test.jar
Server listening on port: 6005
Message without decoding : With UTF-8 encoding: ├®├¿├»
Message with UTF-8 decoding : With UTF-8 encoding: ├®├¿├»
Message with ISO-8859-1 decoding : With UTF-8 encoding: ├®├¿├»
Message without decoding : With ISO-8859-1 encoding: ÚÞ´
Message with UTF-8 decoding : With ISO-8859-1 encoding: ÚÞ´
Message with ISO-8859-1 decoding : With ISO-8859-1 encoding: ÚÞ´
Message without decoding : Without encoding: ÚÞ´
Message with UTF-8 decoding : Without encoding: ÚÞ´
Message with ISO-8859-1 decoding : Without encoding: ÚÞ´
我很沮丧,我尝试解决这个错误至少30个小时,我尝试了我在互联网上找到的所有解决方案,但没有一个有效:(
拜托,我需要帮助!
谢谢你, 圣拉斐尔
答案 0 :(得分:3)
请记住,您的Windows控制台既不使用UTF-8
也不使用ISO-8859-1
。它可能使用CP850
。
例如,您会看到éèï
使用ISO-8859-1
编码为字节E9 E8 EF
,并使用CP850
解码为ÚÞ´
。
我的建议是将所有内容写为UTF-8
,将所有内容都读为UTF-8
,并通过写入文本文件并使用具有UTF-8
功能的编辑器打开来验证输出,而不是相信什么你在控制台看到了。
还要确保Java编译器使用与您编辑Java源代码的编辑器相同的编码(-encoding
)并保存为。我强烈推荐UTF-8
。
此外,URLDecoder.decode(...)
没有按照您的想法行事。也就是说,它最好什么都不做,因为它不是String.getBytes(...)
的反面。除非您实际发送URL编码数据,否则将其删除。
InputStreamReader
已将字节解码为String
s。对于对称性,您应该在另一端使用OutputStreamWriter
。
确保始终始终,始终使用允许您指定编码的方法版本。
String.getBytes()
。new String(byte[])
。new InputStreamReader(InputStream)
。new OutputStreamWriter(OutputStream)
。最好始终使用带有CharsetEncoder
或CharsetDecoder
的版本,因为这些版本可以配置为在失败的编码/解码时抛出异常。
每当您未在任何可能的地方指定编码时,您都依赖于平台默认编码,该编码基本上是具有随机值的全局变量。
您偶然使用平台默认编码的每个地方都是一个错误,可能会等到您或其他人在其他平台或其他国家/地区尝试该程序时才会显示。