运行 Java 工件时显示 Unicode 字符时出现问题,但在 IntelliJ IDEA 中 运行 时一切正常

A problem in showing Unicode Character when running Java artifact, but everything ok while running in IntelliJ IDEA

目标是从数据库中读取记录并将记录写入文件。 运行在 IntelliJ IDEA 中编码时,它写入的 Unicode 字符与数据库内容相同。 但是当我构建工件(Jar 文件)并在 windows 中 运行 时,输出文件显示问号字符“?”而不是正确显示数据库内容。 换句话说,虽然英文字符和数字显示正确,但问题出现在非英文字符(例如波斯字符、阿拉伯字符或...)

java代码的相关部分:

BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile.txt , true), "cp1256"));

while (resultSet.next()) {

    try {
    singleRow = resultSet.getString("CODE") + "|"
            + resultSet.getString("ACTIVITY") + "|"
            + resultSet.getString("TEL") + "|" 
            + resultSet.getString("ZIPCD") + "|"
            + resultSet.getString("ADDR");

    } catch (Exception e) {
        LogUtil.writeLog(Constants.LOG_ERROR, e.getMessage());
    }

    out.write(singleRow + System.getProperty("line.separator"));
}

通过运行ning IntelliJ IDEA DEBUG 模式输出文件内容:

 130143|Active|ابتداي بلوار ميرداماد،کوچه سوم پلاک پنج|524|35254410 
 190730|Active|خیابان زیتون، بین انوشه و زیبا پلاک یک|771|92542001

通过运行宁相应的JAR文件输出文件内容:

130143|Active|35254410|524|??? ? ??? ??????? ????? ????
190730|Active|92542001|771|????? ??? ??????? ????? ??? ??

你能告诉我这个程序有什么问题吗?

您必须按如下方式更改您的代码:

BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile.txt , true), StandardCharsets.UTF_8));
 
while (resultSet.next()) {

    try {
        singleRow = resultSet.getString("CODE") + "|"
                + resultSet.getString("ACTIVITY") + "|"
                + resultSet.getString("TEL") + "|" 
                + resultSet.getString("ZIPCD") + "|"
                + resultSet.getString("ADDR") ;

    } catch (Exception e) {
        LogUtil.writeLog(Constants.LOG_ERROR, e.getMessage());
    }

    byte[] bytes = singleRow.getBytes(StandardCharsets.UTF_8);
    String utf8EncodedString = new String(bytes, StandardCharsets.UTF_8);
    out.write(utf8EncodedString + System.getProperty("line.separator"));
}

String.getBytes()使用系统默认字符集。你可以看到你的环境 字符集来自:

System.out.println("Charset.defaultCharset="+ Charset.defaultCharset());

运行来自IntelliJ时,系统默认字符集取自IntelliJ环境

运行来自JAR文件时,系统默认字符集取自操作系统(最后解释)。

由于您的 windows 和 IntelliJ 环境的不同字符集,您得到不同的输出。

强烈建议明确指定“ISO-8859-1”或“US-ASCII”或“UTF-8”或您想要的任何字符集将字节转换为 vice-versa

的字符串时
singleRow.getBytes(StandardCharsets.UTF_8)

有关更多信息,请参阅 this link


什么是Windows-1252和Windows-1256?

Windows-1252

Windows-1252 or CP-1252 (code page 1252) is a single-byte(0-255) character. encoding of the Latin alphabet, used by default in the legacy components of Microsoft Windows for English and many European languages including Spanish, French, and German. The first 128 code (0-127) is the same as the standard ASCII code. The other codes(128-255) depend on system language ( Spanish, French, German).

Windows-1256

Windows-1256 is a code page used to write Arabic (and possibly some other languages that use Arabic script, like Persian and Urdu) under Microsoft Windows. These are some Windows-1252 Latin characters used for French since this European language has some historic relevance in former French colonies in North Africa. This allowed French and Arabic text to be intermixed when using Windows 1256 without any need for code-page switching (however, upper-case letters with diacritics were not included).

使用Unicode(波斯语)字符时应该怎么办?

由于在波斯语中存在一些具有相似符号的不同字符,例如“”和“ي”,此编码会将“”(U+06cc)替换为“fi”(U+064a),因为Windows-1256没有U+06cc字符。

对于波斯语,在使用 Windows-1256 时使用 UTF-8 编码以避免编码问题请考虑 Windows-1256 仅使用 1 个字节,而 UTF-8 占用更多字节(1 到 4 个字节)。 这些编码的比较是here

如何更改windows默认字符集?

现在在 Microsoft windows Windows-1252 是 [=135= 使用的 默认 编码] 大多数西方国家的系统。

要将 Microsoft windows 默认字符集更改为合适的 Unicode,请遵循 this

如果您按如下方式更改为 Persian,您的默认字符集将更改为 Windows-1256

如何更改特定的软件字符集(有些是为了编程)?

您必须按照说明更改您的特定软件 Unicode。

1- 记事本++

2- 在 xml 文件或字段上

3- 对于 IntelliJ 文件 打开所需的文件进行编辑。 从主菜单中,select 文件 |文件编码或单击状态栏上的文件编码。 Select 弹出窗口中的所需编码。 如果 selected 编码旁边显示 或 ,则表示此编码可能会更改文件内容。在这种情况下,IntelliJ IDEA 打开一个对话框,您可以在其中决定要对文件执行的操作:选择“重新加载”以从磁盘加载编辑器中的文件并将编码更改仅应用于编辑器,或者选择“转换”用您选择的编码覆盖文件。

4-IntelliJ控制台输出编码 IntelliJ IDEA 使用在设置/首选项对话框 Ctrl+Alt+S 的文件编码页面中定义的 IDE 编码创建文件。您可以使用系统默认值或可用编码列表中的 select。默认情况下,此编码会影响控制台输出。如果希望控制台输出的编码与全局IDE设置不同,请配置相应的JVM选项:

  1. 在“帮助”菜单上,单击“编辑自定义 VM 选项”。
  2. 添加-Dconsole.encoding选项并将值设置为必要的编码。例如:-Dconsole.encoding=UTF-8
  3. 重新启动 IntelliJ IDEA.