从导出的jar运行时,将希伯来语写到文件变成乱码

时间:2018-09-06 09:02:19

标签: java encoding jar

我有一个小程序,它用Java编写了一些希伯来字母和一些数字到文件中。 当我从Eclipse运行程序时,希伯来语写得很好,但是如果我将其导出到可执行的JAR文件中并从那里运行,希伯来语就会变得乱七八糟

我的代码:

if (content.length() > 0) {
    FileWriter fileWriter = new FileWriter(path);
    BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
    bufferedWriter.write(content);
    bufferedWriter.close();
}

我还尝试使用OutputStreamWriter自己设置编码:

if (content.length() > 0) {
    BufferedWriter bufferedWriter = new BufferedWriter
        (new OutputStreamWriter(new FileOutputStream(path), "windows-1255"));
    bufferedWriter.write(content);
    bufferedWriter.close();
}

我尝试过的编码:

  • ISO-8859-8
  • windows-1255
  • x-IBM856
  • IBM862
  • IBM424
  • UTF-8

当我从eclipse运行程序时,其中一些返回正确的希伯来语,但是当从JAR文件运行时,所有这些都将希伯来语转换为不同类型的胡言乱语。 我什至不确定代码本身的编码是问题还是解决方法。

我正在Windows 10上使用批处理文件运行JAR。 我的Java版本信息:

  • java版本“ 10.0.1” 2018-04-17
  • Java(TM)SE运行时环境18.3(内部版本10.0.1 + 10)
  • Java HotSpot(TM)64位服务器VM 18.3(内部版本10.0.1 + 10,混合模式)

使用UTF-8时的输出示例

希伯来文件中的一行(由eclipse生成):

210001         188      13 04/09/1804/09/18                                            50.00         1           123456789  לירון קטלן                               הרא"ה 291                                     רמת גן                                                                     6013             

乱码文件的同一行(从JAR生成):

210001         188      13 04/09/1804/09/18                                            50.00         1           123456789  לירון קטלן                               הר�"ה 291                                     רמת גן                                                                     6013    

不要介意多余的空格,它们应该在那里。

1 个答案:

答案 0 :(得分:1)

具有显式编码的第二个代码段正确是跨平台的。

检查内容是否为Unicode:

String content="\u200F\u05D0\u05D1\u05D2\u05D3\u05D4\u200E"; // "אבגדהו"

我使用u编码,所以java源是ASCII,因此如果错误地不同,java编译器的编码和编辑器的编码不会导致 损坏的字符串。

假设content是一个字符串:

if (!content.isEmpty()) {
    content = "\uFEFF" + content; // Add a BOM char in front for Windows
    Path p = Paths.get(path);
    Files.write(p, Collections.singletonList(content), StandardCharsets.UTF_8);
}

这将写入一个UTF-8文件,该文件将引起最少的问题,除非在以色列内部,否则可能会采用特定国家/地区的编码,即Windows-1255。

我添加了BOM字符作为文件的第一个字符,因此Windows可以轻松地识别文件,而不是某些ANSI单字节编码,而是UTF-8 Unicode。

然后就是表示希伯来文字的问题。必须有适当的字体。

您可能会选择编写HTML文件:

content = "<!DOCTYPE html><html lang="he">"
    + "<head><meta charset=\"utf-8\"></head>"
    + "<body><pre>"
    + content.replace("&", "&amp;")
             .replace("<", "&lt;")
             .replace(">", "&gt")
    + "</pre></body></html>";

我发现这比编写BOM更好。

最后一件事是添加LTR('\ u200E')和RTL(从右向左,'\ u200F')标记字符,但是我认为这没问题。


总是在某些地方使用重载方法,其中不存在编码,默认为当前平台编码。

new InputStreamReader(..., StandardCharsets.UTF_8))

等等。