文件编码:保存的内容与读取时不同

时间:2014-09-18 19:04:43

标签: java character-encoding fileinputstream

尝试在java中保存文件时遇到了一些问题。 出于某种原因,我保存文件后得到的内容与我阅读时的内容不同。

我想这与文件编码有关,但不确定。

这是我放在一起的测试代码。这个想法基本上是读取文件,然后再次保存。 当我打开这两个文件时,它们是不同的。

package workspaceFun;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.commons.codec.DecoderException;

public class FileSaveTest {

    public static void main(String[] args) throws IOException, DecoderException{

        String location = "test.location";
        File locationFile = new File(location);

        FileInputStream fis = new FileInputStream(locationFile);

        InputStreamReader r = new InputStreamReader(fis, Charset.forName("UTF-8"));
        System.out.println(r.getEncoding());


        StringBuilder builder = new StringBuilder();
        int ch;
        while((ch = fis.read()) != -1){
            builder.append((char)ch);
        }

        String fullLocationString = builder.toString();             

        //Now we want to save back
        FileOutputStream fos = new FileOutputStream("C:/Users/me/Desktop/test");
        byte[] b = fullLocationString.getBytes();
        fos.write(b);
        fos.close();
        r.close();
    }
}

输入文件的摘录(使用Sublime 2以纯文本形式打开):

40b1 8b81 23bc 0014 1a25 96e7 a393 be1e

并从输出文件:

40c2 b1c2 8bc2 8123 c2bc 0014 1a25 c296

getEncoding方法返回" UTF8"。尝试使用相同的charset doest保存输出文件似乎无法解决问题。

让我感到困惑的是,当我尝试使用apache.commons.codec中的十六进制读取输入文件时:

String hexLocationString2 = Hex.encodeHexString(fullLocationString.getBytes("UTF-8"));

String已经看起来像我的输出文件,而不是输入。

您对可能出现的问题有任何想法吗? 感谢

感兴趣的人的额外信息,我正在尝试阅读eclipse .location文件。

编辑: I placed the file online以便您可以测试代码

2 个答案:

答案 0 :(得分:1)

我相信你正在阅读这条小溪。

您正在使用FileInputStream直接阅读内容,而不是将其包装在InputStreamReader

使用InputStreamReader,您可以确定使用哪个Charset

考虑到InputStream中定义的Charset必须与您期望的相同,因为InputStream不检测字符集,它只是以特定格式读取它们。

尝试以下更改:

InputStreamReader r = new InputStreamReader(new FileInputStream(locationFile), StandardCharsets.UTF_8);

然后代替fos.read()使用r.read()

最后,当写入String时,将获取与读者相同的Charset中的字节

FileOutputStream fos = new FileOutputStream("C:/Users/me/Desktop/test");        
fos.write(fullLocationString.getBytes(StandardCharsets.UTF_8));
fos.close()

答案 1 :(得分:0)

尝试阅读和回写如下:

public class FileSaveTest {

    public static void main(String[] args) throws IOException {

        String location = "D:\\test.txt";

        BufferedReader br = new BufferedReader(new FileReader(location));
        StringBuilder sb = new StringBuilder();

        try {
            String line = br.readLine();

            while (line != null) {
                sb.append(line);
                line = br.readLine();

                if (line != null)
                    sb.append(System.lineSeparator());
            }

        } finally {
            br.close();
        }

        FileOutputStream fos = new FileOutputStream("D:\\text_created.txt");
        byte[] b = sb.toString().getBytes();
        fos.write(b);
        fos.close();

    }
}

测试文件包含Cirillic和Latin字符。

SDFASDF
XXFsd1
12312
іва