String编码(四) 关于文件处理
1.简介
分析JAVA对文件的处理机制。
2.读文件
JAVA中读文件的方式有直接使用FileReader和使用InputStreamReader。
1)FileReader
通过API可知,FileReader将使用默认字符编码处理文件。
1.1)在D:\FileReaderTest创建两个相同内容的TXT文件,fileReaderTest-GBK.txt和fileReaderTest-UTF8.txt
I AM 中国人
?1.2)通过FileReader读取文件内容
package com.siyuan.jdk.test;import java.io.FileReader;import java.io.IOException;import java.nio.charset.Charset;import java.util.Arrays;import org.apache.commons.io.IOUtils;public class FileReaderTest {public static void main(String[] args) throws IOException {System.out.println(Charset.defaultCharset());//String fileName = "D:/FileReaderTest/fileReaderTest-GBK.txt";String fileName = "D:/FileReaderTest/fileReaderTest-UTF8.txt";FileReader reader = null;try {reader = new FileReader(fileName);char[] cBuf = new char[1024];int length = -1;while ((length = reader.read(cBuf, 0, cBuf.length)) != -1) {System.out.print(Arrays.copyOfRange(cBuf, 0, length));}} finally {IOUtils.closeQuietly(reader);}}}??输出结果:
fileReaderTest-GBK.txt
GBKI AM 中国人
?fileReaderTest-UTF8.txt
GBKI AM 涓浗浜?
?通过运行参数-Dfile.encoding="UTF-8"修改默认字符编码输出结果如下:
fileReaderTest-GBK.txt
UTF-8I AM ?й?
?fileReaderTest-UTF8.txt
UTF-8I AM 中国人
?1.3)结论
FileReader使用默认字符编码将文件字节流解码为字符,即Charset.defaultCharset(),可通过运行参数进行修改。
2)InputStreamReader
可以通过向构造函数里头传递字符编码信息来指定字节解码方式。
package com.siyuan.jdk.test;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import org.apache.commons.io.IOUtils;public class InputStreamReaderTest {public static void main(String[] args) throws IOException {// TODO Auto-generated method stubString fileName = "D:/FileReaderTest/fileReaderTest-GBK.txt";String charset = "GBK";//String fileName = "D:/FileReaderTest/fileReaderTest-UTF8.txt";//String charset = "UTF-8";BufferedReader bufReader = null;try {bufReader = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), charset));String buf = null;while ((buf = bufReader.readLine()) != null) {System.out.println(buf);}} finally {IOUtils.closeQuietly(bufReader); // 关闭处理流(装饰)即可关闭底层的字节流}}}?注:必须保证传递的字符编码必须和文件内容编码一致,否则将出错。
3.写文件
FileWriter和OutputStreamWriter的区别也和上述一致。
4.文件名的处理
在D:\FileReaderTest创建一个名为"文件名测试.txt"的文件,在不同的默认编码下获取文件名
4.1)程序代码
package com.siyuan.jdk.test;import java.io.File;import java.nio.charset.Charset;public class FileNameTest {public static void main(String[] args) {System.out.println(Charset.defaultCharset());File file = new File("D:/FileReaderTest");if (file.isDirectory()) for (File tmp : file.listFiles())System.out.println(tmp.getName());}}?4.2)运行结果
默认编码为GBK
GBKfileReaderTest-GBK.txtfileReaderTest-UTF8.txt文件名测试.txt
?默认编码为UTF-8
UTF-8fileReaderTest-GBK.txtfileReaderTest-UTF8.txt文件名测试.txt
?4.3)推断
通过查看源代码发现获取文件名的方法为native类型,从而推断出获取文件名时与系统语言环境相关,而与JVM默认编码无关。
4.4)论证
为了更好的论证结论,将该文件和修改后的程序上传至Linux系统中
打开两个shell窗口,通过export LANG=“zh_CN.UTF-8”和export LANG=“zh_CN.GBK”设置两个不同的语言环境
结果发现:UTF-8环境下会出现乱码,GBK为正常。
可以用同样的方式论证File.createNewFile()方法对文件名的处理方式也是与系统语言环境有关。