简介
本文介绍Java读写文件的方法。
IO包分为字节流和字符流,但是除了这两个流之外,还存在一组字节流一字符流的转换类。
- OutputStreamWriter:Writer的子类,将输出的字符流变为字节流,即将一个字符流的输出对象变为字节流输出对象。
- InputStreamReader:Reader的子类,将输入的字节流变为字符流,即将一个字节流的输入对象变为字符流的输入对象。
如果以文件操作为例,则在内存中的字符数据需要通过OutputStreamWriter变为字节流才能保存在文件中,读取时需要将读入的字节流通过InputStreamReader变为字符流。
写文件
法1:OutputStreamWriter
package com.example.a;
import java.io.*;
public class Demo {
public static void main(String[] args) {
File f = new File ("E:" + File.separator + "test.txt");
Writer out = null;
try {
out = new OutputStreamWriter(new FileOutputStream(f));
out.write("hello world");
out.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
结果:生成了D:\test.txt,内容如下:

法2:PrintStream和PrintWriter
打印流是输出信息最方便的类,主要包含字节打印流(PrintStream)和字符打印流(PrintWriter)。打印流提供了非常方便的打印功能,可以打印任何的数据类型,如小数、整数、字符串等。
PrintStream是 OutputStream的子类,PrintWriter是Writer的子类。与 OutputStream相比起来, PrintStream可以更加方便地输出数据。PrintStream是将OutputStream类重新装饰了一下,就像送别人礼物,需要把礼物包装一下以显得更加好看,所以,这样的设计称为装饰设计模式。
本处使用PrintStream来展示。
package com.example.a;
import java.io.*;
public class Demo {
public static void main(String[] args) {
PrintStream printStream = null;
//通过 FileOutputStream实例化,意味着所有的输出是向文件之中打印
try {
printStream = new PrintStream(new FileOutputStream(
"E:" + File.separator+ "test1.txt"));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
printStream.print("hello ");
printStream.println("world!!!");
printStream.println("1 + 1 : " + 2);
printStream.close();
}
}
执行结果结果:生成了D:\test1.txt,内容如下:

解决文件不存在的问题
在写文件时,若文件不存在,则需要注意。若是绝对路径,会创建文件;若是相对路径,则会报错。
问题复现
package com.example.a;
import java.io.*;
public class Demo {
public static void main(String[] args) {
PrintStream ps = null;
// 通过 FileOutputStream实例化,意味着所有的输出是向文件之中打印
try {
ps = new PrintStream(new FileOutputStream(
"tmp" + File.separator
+ "aa" + File.separator
+ "test.txt"));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
ps.print("hello ");
ps.println("world!!!");
ps.println("1 + 1 : " + 2);
ps.close();
}
}
结果
Exception in thread "main" java.lang.RuntimeException: java.io.FileNotFoundException: tmp\aa\test.txt (系统找不到指定的路径。) at com.example.a.Demo.main(Demo.java:15) Caused by: java.io.FileNotFoundException: tmp\aa\test.txt (系统找不到指定的路径。) at java.io.FileOutputStream.open0(Native Method) at java.io.FileOutputStream.open(FileOutputStream.java:270) at java.io.FileOutputStream.<init>(FileOutputStream.java:213) at java.io.FileOutputStream.<init>(FileOutputStream.java:101) at com.example.a.Demo.main(Demo.java:10)
解决方案
package com.example.a;
import java.io.*;
public class Demo {
public static void main(String[] args) {
write("tmp" + File.separator
+ "aa" + File.separator
+ "test.txt",
"hello world");
}
public static void write(String pathName, String data) {
File file = new File(pathName);
try {
if (!file.exists()) {
if (file.getParentFile() != null) {
// 先得到文件的上级目录,创建上级目录,再创建文件
file.getParentFile().mkdirs();
}
file.createNewFile();
}
PrintStream ps = new PrintStream(new FileOutputStream(file));
ps.print(data);
ps.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
结果
在当前路径下生成tmp\aa\test.txt,内容如下:

读文件
法1:InputStreamReader
D:\test.txt,内容如下:

程序
package com.example.a;
import java.io.*;
public class Demo {
public static void main(String[] args) {
File f = new File("E:"+ File.separator + "test.txt");
Reader reader = null;
//将字节流变为字符流
char[] c = new char[0];
int len = 0;
try {
reader = new InputStreamReader(new FileInputStream(f));
c = new char[1024];
len = reader.read(c);
reader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println(new String(c,0, len));
}
}
执行结果
hello world
法2:Scanner
D:\test.txt,内容如下:

代码
package com.example.a;
import java.io.*;
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
File f = new File("E:"+ File.separator + "test.txt");
Scanner scan = null;
try{
scan = new Scanner(f);
}catch (FileNotFoundException e){
e .printStackTrace();
}
StringBuilder str = new StringBuilder();
while (scan.hasNext()){
str.append(scan.next()).append("\n");
}
System.out.println(str);
scan.close();
}
}
结果
hello world

请先 !