一个很常见的任务就是读取文件到内存,修改后,再写入。
1 读取与写入文本文件工具
Java SE5 在 PrintWriter 中添加了方便的构造器,因此可以很方便地打开一个文本文件进行写入操作。但其他的部分就繁琐咯,所以我们写了一个工具类来简化这一读写操作。它使用 ArrayList 来保存文件的某些行:
public class TextFile extends ArrayList<String> {
/**
* 读取文件
* <p>
* Read a file as a single string
*
* @param file
* @return
*/
public static String read(File file) {
StringBuilder sb = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(new
FileInputStream(file), CommonConstant.ENCODING));
try {
String s;
while ((s = in.readLine()) != null) {
sb.append(s);
sb.append("\n");//每行都添加上换行符(读取时,换行符会被去除)
}
} catch (IOException e) {
e.printStackTrace();
} finally {//保证文件会被正确关闭
in.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return sb.toString();//包含整个文件的字符串
}
/**
* 读取文件
* <p>
* Read a file as a single string
*
* @param fileName
* @return
*/
public static String read(String fileName) {
return read(new File(fileName));
}
/**
* 写入文件
* <p>
* Write a single file in one method call
*
* @param fileName 文件路径
* @param text 要写入的内容
*/
public static void write(String fileName, String text) {
try {
PrintWriter out = new PrintWriter(new File(fileName).getAbsoluteFile());
try {
out.print(text);
} finally {
out.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 构造函数
* <p>
* Read a file, split by any regular expression
*
* @param fileName 文件路径
* @param splitter 文件内容分隔符
*/
public TextFile(String fileName, String splitter) {
super(Arrays.asList(read(fileName).split(splitter)));
// Regular expression split() often leaves an empty String at the first position:
if (get(0).equals("")) remove(0);
}
/**
* 构造函数(一行一行读取)
* Normally read by lines
*
* @param fileName
*/
public TextFile(String fileName) {
this(fileName, "\n");
}
public void write(String fileName) {
try {
PrintWriter out = new PrintWriter(new File(fileName).getAbsoluteFile());
try {
for (String item : this) {
out.println(item);
}
} finally {
out.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 演示使用示例
* <p>
* Simple test
*
* @param args
*/
public static void main(String[] args) {
String file = read("D:\\temp\\1\\1.txt");//读取文件
System.out.println("file:" + file);
write("D:\\temp\\1\\3.txt", file);//写入文件
//拷贝文件
TextFile text = new TextFile("D:\\temp\\1\\3.txt");
text.write("D:\\temp\\1\\4.txt");
/**
* word.txt 内容为 “break,link,line,cook,water” ,我们采用非单词字符作为分隔符,然后把这些单词抽取出来,并排序
*
*/
TreeSet<String> words = new TreeSet<String>(new TextFile("D:\\temp\\1\\word.txt", "\\W+"));
System.out.println("words:" + words);//[break, cook, line, link, water]
System.out.println("words.headSet:" + words.headSet("w"));//只显示前缀大于 w 的单词([break, cook, line, link])
}
}
我们把所有的 IOException 都转型为 RuntimeException,这样调用者就无须使用 try-catch 语句块啦。如果需要 IOException,也可以重载方法,将 IOException 传给调用者。
另一种读取文件的方法是使用 Java SE5 中引入的 java.util.Scanner 类,但它只能读取文件。这个类主要用来创建编程语言的扫描器的。
源代码中的 CommonConstant.ENCODING是 UTF-8。
2 读取二进制文件工具
public class BinaryFile {
public static byte[] read(File bFile) throws IOException {
BufferedInputStream bf = new BufferedInputStream(new FileInputStream(bFile));//接受 File 参数
try {
byte[] data = new byte[bf.available()];//生成恰当的数组尺寸
bf.read(data);//填充数组
return data;
} finally {
bf.close();
}
}
public static byte[] read(String bFile) throws IOException {
return read(new File(bFile).getAbsoluteFile());
}
}
2017-11-1
* [fix] 读取文件,解决中文乱码问题。