【问题标题】:Java encoding - corrupted French charactersJava 编码 - 损坏的法语字符
【发布时间】:2021-06-26 17:32:34
【问题描述】:

我有一个系统,我从第三方获得法语文本,但我很难让它可读。

String frenchReceipt = "RETIR�E"; // The original Text should be "RETIRÉE"

我尝试了所有可能的组合来使用 UTF-8 和 ISO-8859-1 的编码转换字符串

String frenchReceipt = "RETIR�E"; // The original Text should be "RETIRÉE"

byte[] b1 = new String(frenchReceipt.getBytes()).getBytes("UTF-8"); 
System.out.println(new String(b1));  // RETIR�E

byte[] b2 = new String(frenchReceipt.getBytes()).getBytes("ISO-8859-1"); 
System.out.println(new String(b2));  // RETIR�E

byte[] b3 = new String(frenchReceipt.getBytes(), "UTF-8").getBytes(); 
System.out.println(new String(b3));  // RETIR?E 

byte[] b4 = new String(frenchReceipt.getBytes(), "UTF-8").getBytes(); 
System.out.println(new String(b4));  //RETIR?E

byte[] b5 = new String(frenchReceipt.getBytes(), "ISO-8859-1").getBytes("UTF-8"); 
System.out.println(new String(b5));  //RETIR�E

byte[] b6 = new String(frenchReceipt.getBytes(), "UTF-8").getBytes("ISO-8859-1"); 
System.out.println(new String(b6));  //RETIR?E

byte[] b7 = new String(frenchReceipt.getBytes(), "UTF-8").getBytes("UTF-8"); 
System.out.println(new String(b7));  //RETIR�E

byte[] b8 = new String(frenchReceipt.getBytes(), "ISO-8859-1").getBytes("ISO-8859-1"); 
System.out.println(new String(b8));  //RETIR�E

正如您所见,没有什么能解决问题。

请指教。

更新: 第三方合作伙伴确认以“ISO-8859-1”编码发送到我的应用程序的数据

【问题讨论】:

  • System.out 的控制台使用什么编码?
  • stackoverflow.com/questions/6543548/…。字符�被编码为EF BF BD,答案中提到了。
  • @mayamar 默认文本文件编码为:“Cp1252”。但我也尝试将其更改为“UTF-8”和“ISO-8859-1”,但并没有解决问题。

标签: java encoding utf-8 iso-8859-1


【解决方案1】:

� 只是一个替换字符 (EF|BF|BD UTF-8),用于指示系统无法呈现正确符号时的问题。 这意味着您没有机会将 � 转换为 É。

frenchReceipt 不包含任何由于声明而可以转换为 É 的字节序列:

String frenchReceipt = "RETIR�E";

您下面的代码 sn-p 应该可以正常工作,但您必须使用正确的字节源。

byte[] b2 = new String(frenchReceipt.getBytes()).getBytes("ISO-8859-1");
System.out.println(new String(b2));

因此,如果您从数据源中按字节读取“RETIRÉE”并获得52|45|54|49|52|C9|45(应为 ISO-8859-1),那么您将获得正确的结果。 如果数据源已经有字节序列EF|BF|BD,那么你唯一的选择就是search&replace,但在这种情况下,ä和É没有区别。

更新: 由于数据是通过 TCP 传递的

new BufferedReader(new InputStreamReader(connection.getInputStream(),"ISO-8859-1"))

解决了这个问题。

【讨论】:

  • 你能告诉我具体该怎么做吗?我不明白你答案的最后一部分。何从数据源按字节读取“RETIRÉE”并得到 52|45|54|49|52|C9|45 ??
  • “如何阅读”问题的答案取决于数据源(XML、数据库、二进制流等)。 “RETIR�E”的真实数据来源是什么?
  • 根据文档,它是“纯文本”编码为“ISO-8859-1”
  • 说清楚:我得到的响应是一系列参数分隔字段分隔符(FS)并以(EOT)字段结尾。例如:00[FS]RETIR�E[FS]FR[EOT] 当然FS和EOT没有括号[],只是为了可读性而添加
  • TCP 连接没有字符编码的概念。尝试使用 BufferedReader 读取流 br = new BufferedReader(new InputStreamReader(connection.getInputStream(),"ISO-8859-1"));
猜你喜欢
  • 2013-10-19
  • 1970-01-01
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-22
  • 2017-10-16
  • 1970-01-01
相关资源
最近更新 更多