JAVAIO编码的乱码问题和解决办法

先做一个相关说明,文件是采用byte存储的,文本是采用某种编码的char数组,文本文件是采用某种编码的字符数组采用字节的形式存储的。 
好了,了解以上这些就好办了,下面进入正题吧。

下面通过文件的复制进行简单的举例介绍~我新建了一个文本文件并采用了xxx编码。

那么如果进行的是fileinputstream的read()方法或是bufferedfileinputstream的read()方法进行读入操作,它读入内存的是字节(单字节形式读入),也可以是read(数组对象或是指向实例化数组对象的引用,数组开头,数组长度)的方式进行字节数组的读入,你在控制台打印输出字节(read()的单字节读入的时候已经进行了类型转化,转化(返回值)为int,过程是无符号的字节前面填充24位0)或字节数组。

如果进行的是fileoutputstream的或者是bufferedfileoutputstream的write()方法,它写出的是单字节,当然也可以跟上面的read()方法类似,采用write(数组对象或是指向实例化数组对象的引用,数组开头,数组长度)的方式进行字节数组的写入操作,如果采用的是write()单字节的写入,里面的参数如果是int将自动转化为字节,该字节采用int的低八位。

注意全程的过程,就四种类型①不带缓冲单字节操作②带缓冲单字节操作(buffered)③不带缓冲字节数组操作④带缓冲的字节数组操作(buffered)。全程都是字节与字符无关也就不涉及编码,buffered是缓冲区就是为了实现文件复制的加速,大家略带了解。

好了,上面文件复制全程不涉及编码,那么经过本人无数次的测试和查阅api文档发现,假如你准备将A文本文件复制给B文本文件,那么A采用utf-8编码,而你的java工程采用默认gbk编码,那么没关系,它复制到B文本文件的还是utf-8编码,因为它的输入输出采用的是字节为单位,不涉及编码。如果A是Unicode编码的生成的B也是采用Unicdoe编码,这就是字节单位编码的java无关。

下面介绍inputstreamreader和outputstreamwriter

它俩有意思了,inputstreamreader对象的read()方法读入的是字符,对的,是字符,而不是字节!那么问题来了字符是字节组成的但是它涉及编码,如果你的A文件通过inputstreamreader进行写入内存操作,它可以是read()方法,也可以是是read(数组)方法,它们分别写入单字符和字符数组。这个时候你可以实现控制台打印啦~,假如A文件(同上)是UTF-8编码,你的java工程默认采用GBK编码,恭喜你,控制台乱码在向你招手。

那么,如何解决呢?很简单,inputstreamreader创建对象的时候添加编码格式参数,选择与A文件编码相同即可。那么你的java工程就采用指定编码对你这个inputstreamreade对象进行相关操作了,你在打印台输出的时候会发现,当当当,控制台不乱码了,然后可以通过outputstreamwriter输出到指定文件B啦。

类似inputstreamreader,你的inputstreamreader也可以选择编码,如果不选择的话让你writer(单字符)或wtier(字符数组)写出操作完毕之后,B文件会采用计算机默认提供的编码,当然B文件也不会乱码,它的输出是java工程通过正确接受字符之后系统默认给你做了相应的转化。就是你的控制台是UTF-8编码,没有乱码,你输出成了ANSI依旧没有乱码,字符复制的关键就在于系统是否(通过相同编码方式)正确接受了A文件读入的字符组。

同样的,你也可以在inputstreamwriter的构造函数了添加指定编码类型,如上所讲,系统会将它正确接受的字符组,转化为你设定的编码方式,也就是指定B文件编码方式。

好了,一口气讲了这么多,大家回想一下。

下面再讲filereader和filewrtier这俩货,它们的读入和写出采用的也是字符单位,那么问题来了,如果A文件采用UTF-8,java工程采用的是GBK那么恭喜你,当啷啷,控制台输出乱码伺候,更别想B文件了,细心的你该说了,我在他们的构造函数添加编码方式参数啊,恭喜你,这俩对象没有带编码参数的构造函数, 所以一般情况下不推荐这种用法。

你可能感兴趣的:(JAVA)