Java编写Shift-JIS CSV格式文件

时间:2016-08-24 10:54:49

标签: java csv outputstream fileoutputstream shift-jis

我目前正在使用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的结果:

It was not in Shift-JIS formt

它不是Shift-JIS格式,而且另一个试验中的单词也是不正确的:

dat的结果:

enter image description here

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

出了什么问题?或者内容不正确?

谢谢!

3 个答案:

答案 0 :(得分:0)

除了以下代码之外,您的大多数代码都很好:

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

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

因此线条变得更简单:

    fp.write(dat2);

顺便说一句:

表达式

new String(dat2.getBytes("Shift_JIS")

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

P.S。

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

答案 1 :(得分:0)

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

对于上面给出的样本, dat 为全宽, dat2 为半宽。

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

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

The result as below :
カヨ ハラダ

答案 2 :(得分: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 ++可以恢复一个文件的内容,并且无法恢复另一个文件的内容。