【问题标题】:Writing hebrew to file turns to gibberish when run from exported jar从导出的 jar 运行时,将希伯来语写入文件会变成乱码
【发布时间】:2019-02-11 11:58:40
【问题描述】:

我有一个用 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    

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

【问题讨论】:

  • 为什么不使用 UTF-8?据我了解,它应该支持希伯来语脚本
  • UTF-8 是当今更多机器上的标准。
  • 也试过 UTF-8,从 eclipse 运行时它可以工作,但从 JAR 运行时会出现乱码(与 windows-1255 相同),更新了问题
  • 顺便说一句,这可能不会导致您的问题,但关闭 BufferedWriter 不会刷新或关闭底层编写器。您需要显式刷新或关闭底层编写器以使其刷新。我不确定为什么你甚至需要一个 BW,因为无论如何你都要在写入后立即关闭流。
  • 正如我在问题中提到和编辑的,我尝试使用 UTF-8。如果我从 Eclipse 运行程序,它会编写正确的希伯来语,只有当我将它作为 JAR 文件运行时,它才会变为 gibrish。

标签: java encoding jar


【解决方案1】:

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

检查内容是否正常 Unicode:

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

我使用了 u-encoding,所以 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 (Right-To-Left, '\u200F') 标记字符,但我认为这没有问题。


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

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

等等。

【讨论】:

  • 我尝试添加 BOM 字符,但无济于事。我的问题不是查看此文件或在某处显示它,我正在获取此文件并将其导入到不同的程序中。如果我导入直接从 eclipse 生成的文件,希伯来语很好,如果我导入从 JAR 创建的文件,它都是胡言乱语,查看这些文件具有相同的效果,但这不是真正的问题,就像希伯来语不是写的从 JAR 运行时创建文件时作为希伯来语
  • 感谢您的 cmets 设法找到问题,问题是我的 InputStreamReader 创建,它缺少我在编写器中使用的编码。 InputStreamReader(inputStream, Charset.forName("UTF-8")); 是修复它的原因。如果您想编辑答案以包含此内容,我会将其标记为正确答案,或者我可以自己回答,请告诉我:)
  • 很高兴您发现了错误。其实这个错误在最初的cmets中或多或少提到过,但是很容易被这样的东西困住。
  • 我不小心在这里标记了最有帮助的评论,有没有办法撤消它?
猜你喜欢
  • 2012-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-02
  • 2023-03-23
相关资源
最近更新 更多