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
GBK
I AM 中国人
fileReaderTest-UTF8.txt
GBK
I AM 涓浗浜?
通过运行参数-Dfile.encoding="UTF-8"修改默认字符编码输出结果如下:
fileReaderTest-GBK.txt
UTF-8
I AM �й�
fileReaderTest-UTF8.txt
UTF-8
I 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 stub
String 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
GBK
fileReaderTest-GBK.txt
fileReaderTest-UTF8.txt
文件名测试.txt
默认编码为UTF-8
UTF-8
fileReaderTest-GBK.txt
fileReaderTest-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()方法对文件名的处理方式也是与系统语言环境有关。