首页 > 解决方案 > 运行 Java 工件时显示 Unicode 字符的问题,但在 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"));
}

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

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

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

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

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

标签: javaunicodeutf-8character-encoding

解决方案


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

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”或任何您想要的字符集,反之亦然

singleRow.getBytes(StandardCharsets.UTF_8)

查看此链接了解更多离子化信息


什么是 Windows-1252 和 Windows-1256?

Windows-1252

Windows-1252 或 CP-1252(代码页 1252)是单字节(0-255) 字符。拉丁字母的编码,默认情况下在 Microsoft Windows 的旧组件中用于英语和许多欧洲语言,包括西班牙语、法语和德语。前 128 位代码 (0-127) 与标准 ASCII 代码相同。其他代码(128-255)取决于系统语言(西班牙语、法语、德语)。

Windows-1256

Windows-1256 是一个代码页,用于在 Microsoft Windows 下编写阿拉伯语(可能还有其他一些使用阿拉伯语脚本的语言,如波斯语和乌尔都语)。这些是用于法语的一些Windows-1252拉丁字符,因为这种欧洲语言在北非的前法国殖民地具有一定的历史意义。这允许在使用Windows 1256时混合使用法语和阿拉伯语文本,而无需切换代码页(但是,不包括带有变音符号的大写字母)。

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

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

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

如何更改windows默认字符集?

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

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

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

在此处输入图像描述

如何更改特定的软件字符集(一些用于编程)?

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

1-记事本++
在此处输入图像描述

2-关于 xml 文件或字段 在此处输入图像描述

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

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

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

推荐阅读