Java 文件的读取与写入
## 读取文件
### 以字节为单位读取文件(FileInputStream)
常用于读二进制文件,如图片、声音、影像等文件。
```
File file = new File("filePath");
try (InputStream in = new FileInputStream(file);) {
// 一次读4个字节
byte[] bytes = new byte[4];
// 读取到的字节数量
int readCount = 0;
// 读入4个字节到字节数组中
while ((readCount = in.read(bytes)) != -1) {
System.out.write(bytes, 0, readCount);
}
} catch (Exception e) {
e.printStackTrace();
}
```
### 以字符为单位读取文件(InputStreamReader)
常用于读文本,数字等类型的文件。
```
File file = new File("filePath");
try (Reader reader = new InputStreamReader(new FileInputStream(file));) {
// 一次读30个字符
char[] chars = new char[30];
// 读取到的字节数量
int readCount = 0;
while ((readCount = reader.read(chars)) != -1) {
for (int i = 0; i < readCount; i++) {
System.out.print(chars[i]);
}
}
} catch (Exception e) {
e.printStackTrace();
}
```
### 以行为单位读取文件内容(BufferedReader)
常用于读面向行的格式化文件。
```
File file = new File("filePath");
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line = null;
// 一次读入一行,直到读入null为文件结束
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
```
### 一次读取所有行(Files.readAllLines)
使用nio的Files.readAllLines可以一次性读取所有行
```
List<String> lines = Files.readAllLines(Paths.get("filePath"));
for (String line : lines) {
System.out.println(line);
}
```
## 写入文件
### 以字节为单位写文件(FileOutputStream)
```
File file = new File("D:/file.txt");
try (OutputStream out = new FileOutputStream(file);) {
String content = "枫桥夜泊\n张继\n月落乌啼霜满天,\n江枫渔火对愁眠。";
out.write(content.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
```
### 以字符为单位写文件(OutputStreamWriter)
```
File file = new File("D:/file.txt");
try (Writer writer = new OutputStreamWriter(new FileOutputStream(file));) {
String content = "枫桥夜泊\n张继\n月落乌啼霜满天,\n江枫渔火对愁眠。";
writer.write(content);
} catch (IOException e) {
e.printStackTrace();
}
```
### 以行为单位写文件(PrintWriter)
```
try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter("D:/file.txt")));) {
writer.println(" 枫桥夜泊 "); // 写字符串
writer.print(true); // 写入布尔类型
writer.print(666); // 写入整数类型
writer.println(); // 换行
writer.flush(); // 写入刷新文件
} catch (IOException e) {
e.printStackTrace();
}
```
### 另一种以行为单位写文件(FileWriter)
```java
String path = "filePath";
// 第二个参数true表示以追加形式写文件
try (FileWriter writer = new FileWriter(path, true);) {
writer.write("new line");
} catch (IOException e) {
e.printStackTrace();
}
```
### 使用RandomAccessFile追加写入
```
try {
String path = "filePath";
// 打开一个随机访问文件流,按读写方式
RandomAccessFile randomFile = new RandomAccessFile(path, "rw");
// 将写文件指针移到文件尾。
randomFile.seek(randomFile.length());
randomFile.writeBytes("new string");
randomFile.close();
List<String> lines = Files.readAllLines(Paths.get(path));
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
```
### FileWriter 与 PrintWriter 的区别
#### JAVA DOC 的定义
> FileWriter is a convenience class for writing character files. The constructors of this class assume that the default character encoding and the default byte-buffer size are acceptable. To specify these values yourself, construct an OutputStreamWriter on a FileOutputStream.
>
> FileWriter 可以很方便的编写字符型文件,它的构造方法设置了默认的字符编码和字节缓冲区大小。如果要自行设置,可以在 FileOutputStream 上构造一个 OutputStreamWriter。
> PrintWriter prints formatted representations of objects to a text-output stream. This class implements all of the print methods found in PrintStream. It does not contain methods for writing raw bytes, for which a program should use unencoded byte streams.
>
> PrintWriter 将对象以格式化的形式打印到文本输出流,该类实现了 PrintStream 中的所有 print 方法。它不包含写入原始字节的方法,对于字节,程序应该使用未编码的字节流进行写入。
主要的区别是PrintWriter提供了一些额外的方法用于格式化输出,如println、printf。
如果发生任何I/O异常,FileWriter会抛出IOException,而PrintWriter不会抛出IOException,它会设置一个boolean标志,该标志可以通过调用checkError()方法获取。
PrintWriter在每次写入数据后会自动调用flush()方法,而FileWriter则需要自行调用flush()方法。