0

我目前正在对 Shift-JIS 格式的输出 CSV 文件进行一些测试,但不知何故,我发现在不同日文字符的试验中很奇怪,如下所示:

我的代码:

try {
        String dat2 = "カヨ ハラダ";
        String dat = "2バイト文字出力";
        String fileName = "C:/Users/CR/Desktop/test2.txt";

        FileOutputStream fos = new FileOutputStream(fileName);
        OutputStreamWriter osw = new OutputStreamWriter(fos, "Shift_JIS");
        BufferedWriter fp = new BufferedWriter(osw);

        fp.write(new String(dat2.getBytes("Shift_JIS"));
        fp.newLine();

        fp.flush();
        fp.close();
        fos.close();

    } catch (Exception ex) {
        throw new Exception(ex);
    }

dat2 的结果:

它不是 Shift-JIS 格式

它不是 Shift-JIS 格式,并且单词也不正确,因此再次试用:

dat 的结果:

在此处输入图像描述

这也可以以预期的格式正确显示。

有什么事吗?还是内容不正确?

谢谢 !

4

3 回答 3

1

您的大部分代码都很好,除了以下行:

    fp.write(new String(dat2.getBytes("Shift_JIS"));

Java 字符串(或多或少)是编码中性的。当您将字符串写入文件(或通过网络发送)时,编码开始发挥作用。在您的情况下,编码转换由您正确设置的OutputStreamWriter处理。

所以这条线变得更简单了:

    fp.write(dat2);

顺便提一句:

表达方式

new String(dat2.getBytes("Shift_JIS")

首先将字符串dat2转换为Shift_JIS编码的字节数组,然后将字节数组转换为使用默认编码(可能是 UTF-8)的字符串,从而使用错误的编码解码字节数组。

附言

还有一件事。诸如 CSV 文件之类的文本文件无法指示用于编写它们的编码(例外:带有 BOM 的 UTF)。只有启发式方法可以做出很好的猜测。因此,当您在文本编辑器中打开它们时,您必须检查它们是否以正确的编码打开并在必要时进行修复。在您的第一个屏幕截图中,状态栏中显示“ANSI”。这几乎不是你想要的。

于 2016-08-24T11:05:32.093 回答
0

我已经运行了下面的程序:

import java.io.*;

public class Hoge {
    public static void main(String[] args) {
        try {
            {
                String dat = "2バイト文字出力";
                String fileName = "./FullWidth.txt";

                FileOutputStream fos = new FileOutputStream(fileName);
                OutputStreamWriter osw = new OutputStreamWriter(fos, "Shift_JIS");
                BufferedWriter fp = new BufferedWriter(osw);

                fp.write(new String(dat.getBytes("Shift_JIS")));
                fp.newLine();

                fp.flush();
                fp.close();
                fos.close();
            }
            {
                String dat2 = "カヨ ハラダ";
                String fileName = "./HalfWidth.txt";

                FileOutputStream fos = new FileOutputStream(fileName);
                OutputStreamWriter osw = new OutputStreamWriter(fos, "Shift_JIS");
                BufferedWriter fp = new BufferedWriter(osw);

                fp.write(new String(dat2.getBytes("Shift_JIS")));
                fp.newLine();

                fp.flush();
                fp.close();
                fos.close();
            }
        } catch (Exception ex) {
            // NOP
        }
    }
}

的内容FullWidth.txt是(十六进制):

3F 51 3F 6F 3F 43 3F 67 3F 3F 3F 3F 3F 6F 3F 3F 0A

Shift JIS 编码中的字符串2バイト应该是82 51 83 6F 83 43 83 67. 所以我认为 Notepad++ 将编码识别为 Shift JIS,并以某种方式恢复了每个字符的第一个字节。

另一方面,的内容HalfWidth.txt是(十六进制):

3F 3F 20 3F 3F 3F 3F 0A

所以我认为 Notepad++ 无法识别这个文件的编码。

简而言之:两个文件都是错误的。不小心 Notepad++ 可以恢复一个文件的内容,而无法恢复另一个文件的内容。

于 2018-02-07T16:07:03.507 回答
0

问题似乎是由日语单词引起的 - 全角或半角片假名字符。

对于上面给出的示例,dat为全角,dat2为半角。

所以我尝试使用 ICU4J 将半角转换为全角,然后它可以成功写入 Shift-JIS 格式的 CSV。

Transliterator transliterator = Transliterator.getInstance("Halfwidth-Fullwidth");
String converted = transliterator.transliterate("カヨ ハラダ"); 

The result as below :
カヨ ハラダ
于 2016-08-25T10:02:22.980 回答