java 文件读取写入的编码问题
2011-10-25 23:47
363 查看
关于编码解码的知识背景:
内 编码 --->> 目
容 <<----解码 标
编码解码跟翻译语言一样。内容是本质的东西,无论怎么编码,它所表达的内容不能变。
而无论怎么编码解码,表现形式都是字节数组,它的值会随着编码解码方式的不同而不同。
编码解码要做的,就是对这些byte数组进行操作,将它还原成我们需要的内容。
对于一段汉字的编码解码,汉字本身就是内容文件,我们需要将他们用数字的形式表示,即编码为对应的二进制串(目标)
常见的字符集:
ANSI :ASCII字符集,以及由此派生并兼容的字符集,如:GB2312(汉字支持,GB是“国标”的缩写),对GB2312向下兼容的GBK(其中能表达的汉字数量比GB2312多),正式的名称为MBCS(Multi-Byte Chactacter System,多字节字符系统),通常也称为ANSI字符集。
UNICODE: 由于每种语言都制定了自己的字符集,导致最后存在的各种字符集实在太多,在国际交流中要经常转换字符集非常不便。因此,产生了Unicode字符集,它固定使用16 bits(两个字节)来表示一个字符,共可以表示65536个字符。标准的Unicode称为UTF-16(UTF:UCS Transformation Format
,每两个字节作为一个编码单元,编码效率高。这让能够用一个字节存放的ASCII字符浪费了一个字节,不适于网络传输,多用于本地的编码)。后来为了双字节的Unicode能够在现存的处理单字节的系统上正确传输,出现了UTF-8(变长编码,有更好的鲁棒性:UTF16顺序编码,如果中间丢失一个bit位,将全盘皆输,但UTF8的编码方式中,每个单元都有一个特定几个bit位的头,这让它能抵抗这种情况),使用类似MBCS的方式对Unicode进行编码。(Unicode字符集有多种编码形式)
--------------------------------------------------------------************正文************---------------------------------------------------
java中读取文件的解码
文件以字节的形式存储在磁盘,这些数据实际上是文件的内容通过某种字符集编码后的结果,而我们读取文件后对文件的处理就是对这些数据的解码。
按照java IO 的框架,Java读取文件的方式总体可以分为两类:按字节读取和按字符读取。下面依次分析。
按字节读取
按字节读取的层次结构是各种stream 。可以使用InputStream.read()方法来读取字节。需要的话,可以将字节数组转换成String字符串。
而编码也就隐式发生在由字节数组转换到字符串数组的过程中。
参见)]String构造函数的doc , 如上的转换实际上使用的是系统的默认字符集。如果需要制定字符集解码,可以使用
只要能用文件的编码字符集进行解码,就不会出现乱码问题。
以下为实践代码。我存储了a.txt到我的用户目录下。内容为: biaobiaoqi编码问题
分别用GB2312 ,GBK ,UTF8, UTF16 并用system.out.println显示,结果如下:
可以推断,a.txt的文本文件编码为ANSI,GBK向下兼容GB2312,所以两者都能显示。而UTF则不是那么顺利了。
按字符读取
按字符读取的层次体系(各种Reader、 Writer类)的出现是为了适应国际化(thinking in java)。不同语言的不同字符集对字符的处理是不一样的。
实际上,之前介绍的将btye数字转换成String 的过程就是Reader们所要做的。他们以字节读取类为基础,将字节数组转换为相应字符集的字符串。
方法如下:
不指定第二个参数的话,也会使用系统的默认的字符集编码了。
输出文件编码
同样的道理,在输出文件的时候,会遇到编码问题。
对于字节输出流
由于已经是字节的形式,会被直接的保存为文件,而不涉及编码:编码已经在字符串到字节数组的过程中完成。
那么,字符串到字节数组的转换的编码如何控制呢?
一般情况,我们会使用String中的getByte()方法。与String的构造一样,如果不加参数,会使用系统的默认字符集编码。自定义的编码方式为byte[] getByte(Charset c)。
字符输出流
道理一样。他的底层也是利用了字节输出流实现。OutputStreamWriter操作如下:
更深入的探讨,可以发现,其实在Console端的显示,也是要利用到编码解码的问题的。
在system.out.println时,会使用系统的默认编码,而console显示如果使用了其他字符集解码,则会出现乱码问题。
在Eclipse下,可以尝试修改console显示的解码字符集。Run configuration --> common ,修改之后,相信就会在system.out.println后出现乱码了^_^
总之,只要编码跟解码对应统一,在统一的java平台下,就不会出现乱码了。
内 编码 --->> 目
容 <<----解码 标
编码解码跟翻译语言一样。内容是本质的东西,无论怎么编码,它所表达的内容不能变。
而无论怎么编码解码,表现形式都是字节数组,它的值会随着编码解码方式的不同而不同。
编码解码要做的,就是对这些byte数组进行操作,将它还原成我们需要的内容。
对于一段汉字的编码解码,汉字本身就是内容文件,我们需要将他们用数字的形式表示,即编码为对应的二进制串(目标)
常见的字符集:
ANSI :ASCII字符集,以及由此派生并兼容的字符集,如:GB2312(汉字支持,GB是“国标”的缩写),对GB2312向下兼容的GBK(其中能表达的汉字数量比GB2312多),正式的名称为MBCS(Multi-Byte Chactacter System,多字节字符系统),通常也称为ANSI字符集。
UNICODE: 由于每种语言都制定了自己的字符集,导致最后存在的各种字符集实在太多,在国际交流中要经常转换字符集非常不便。因此,产生了Unicode字符集,它固定使用16 bits(两个字节)来表示一个字符,共可以表示65536个字符。标准的Unicode称为UTF-16(UTF:UCS Transformation Format
,每两个字节作为一个编码单元,编码效率高。这让能够用一个字节存放的ASCII字符浪费了一个字节,不适于网络传输,多用于本地的编码)。后来为了双字节的Unicode能够在现存的处理单字节的系统上正确传输,出现了UTF-8(变长编码,有更好的鲁棒性:UTF16顺序编码,如果中间丢失一个bit位,将全盘皆输,但UTF8的编码方式中,每个单元都有一个特定几个bit位的头,这让它能抵抗这种情况),使用类似MBCS的方式对Unicode进行编码。(Unicode字符集有多种编码形式)
--------------------------------------------------------------************正文************---------------------------------------------------
java中读取文件的解码
文件以字节的形式存储在磁盘,这些数据实际上是文件的内容通过某种字符集编码后的结果,而我们读取文件后对文件的处理就是对这些数据的解码。
按照java IO 的框架,Java读取文件的方式总体可以分为两类:按字节读取和按字符读取。下面依次分析。
按字节读取
按字节读取的层次结构是各种stream 。可以使用InputStream.read()方法来读取字节。需要的话,可以将字节数组转换成String字符串。
而编码也就隐式发生在由字节数组转换到字符串数组的过程中。
String str = new String(byteArray);
参见)]String构造函数的doc , 如上的转换实际上使用的是系统的默认字符集。如果需要制定字符集解码,可以使用
, java.nio.charset.Charset)]String(byte[] bytes, Charset charset)构造函数。
只要能用文件的编码字符集进行解码,就不会出现乱码问题。
以下为实践代码。我存储了a.txt到我的用户目录下。内容为: biaobiaoqi编码问题
package biaobiaoqi.thinkingInJava; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class Test { public static void main(String[] args){ try { FileInputStream in = new FileInputStream("/home/biaobiaoqi/a.txt"); byte[] bytes = new byte[100]; while((in.read(bytes)) != -1); in.close(); String strGB2312 = new String(bytes,"GB2312"); String strGBK = new String(bytes,"GBK"); String strUTF8 = new String(bytes,"UTF-8"); String strUTF16 = new String(bytes,"UTF-16"); System.out.println("strGB2312: "+strGB2312); System.out.println("strGBK: "+strGBK); System.out.println("strUTF8: "+strUTF8); System.out.println("strUTF16: "+strUTF16); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
分别用GB2312 ,GBK ,UTF8, UTF16 并用system.out.println显示,结果如下:
strGB2312: biaobiaoqi编码问题 strGBK: biaobiaoqi编码问题 strUTF8: biaobiaoqi�������� strUTF16: 扩慯扩慯煩뇠싫컊쳢
可以推断,a.txt的文本文件编码为ANSI,GBK向下兼容GB2312,所以两者都能显示。而UTF则不是那么顺利了。
按字符读取
按字符读取的层次体系(各种Reader、 Writer类)的出现是为了适应国际化(thinking in java)。不同语言的不同字符集对字符的处理是不一样的。
实际上,之前介绍的将btye数字转换成String 的过程就是Reader们所要做的。他们以字节读取类为基础,将字节数组转换为相应字符集的字符串。
方法如下:
InputStreamReader in = new InputStreamReader(new FileInputStream(“demo.txt”),”UTF-8”);
不指定第二个参数的话,也会使用系统的默认的字符集编码了。
输出文件编码
同样的道理,在输出文件的时候,会遇到编码问题。
对于字节输出流
由于已经是字节的形式,会被直接的保存为文件,而不涉及编码:编码已经在字符串到字节数组的过程中完成。
那么,字符串到字节数组的转换的编码如何控制呢?
一般情况,我们会使用String中的getByte()方法。与String的构造一样,如果不加参数,会使用系统的默认字符集编码。自定义的编码方式为byte[] getByte(Charset c)。
String str = "编码问题,biaobiaoqi"; FileOutputStream out = new FileOutputStream("/home/biaobiaoqi/b.txt"); out.write(str.getBytes("UTF-16")); out.close();
字符输出流
道理一样。他的底层也是利用了字节输出流实现。OutputStreamWriter操作如下:
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(“dd.txt”),”UTF-8”);
更深入的探讨,可以发现,其实在Console端的显示,也是要利用到编码解码的问题的。
在system.out.println时,会使用系统的默认编码,而console显示如果使用了其他字符集解码,则会出现乱码问题。
在Eclipse下,可以尝试修改console显示的解码字符集。Run configuration --> common ,修改之后,相信就会在system.out.println后出现乱码了^_^
总之,只要编码跟解码对应统一,在统一的java平台下,就不会出现乱码了。
相关文章推荐
- java按指定编码写入和读取文件内容
- Java底层代码实现单文件读取和写入(解决中文乱码问题)
- Java文件流 编码问题 - 读取文件时指定字符编码
- java读取文件内容的编码问题
- Java读取、写入文件如何解决乱码问题
- java字节流和字符流操作文件,指定编码写入和读取,递归创建上层目录
- java处理字符编码的常见问题(最近在弄字符串设置编码写入文件)
- Java IO操作之文件读取与写入 无乱码FileOutputStream FileInputStream使用-IO写utf-8乱码问题
- java读取文件内容的编码问题
- JAVA从UTF-8编码文件读取字符串时,前边有问号的问题
- android读取文件时乱码的问题,以及eclipse中java编码查看方式
- java按指定编码写入和读取文件内容的类分享
- Java 读取写入文件乱码问题解决
- Java 读写文件的编码问题——读取是重点
- java按指定编码写入和读取文件内容的类
- 关于python3.x读取写入文件时编码报错问题
- java读取ANSI编码或者UTF-8编码文件乱码问题解决
- java按指定编码写入和读取文件内容的类
- java按指定编码写入和读取文件内容的类
- Java读取、写入文件如何解决乱码问题