1 字符流引入
2 输入字符流
3 输出字符流
4 缓冲输入字符流
5 缓冲输出字符流
1 字符流引入
public class Demo1 {
public static void main(String[] args) throws IOException {
// writeTest();
readTest();
}
// 使用字节流读中文。
public static void readTest() throws IOException {
File file = new File("G:\\a.txt");
FileInputStream fileInputStream = new FileInputStream(file);
/*
int content = 0;
while((content = fileInputStream.read()) != -1) {
System.out.print((char) content); // 会出现乱码。原因:一个中文在GBK码表中默认的是占两个字节,目前每次只读了一个字节,所以不是一个完整的中文。
}
*/
int length = 0;
byte[] buf = new byte[2];
for(int i = 0; i < 3; i ++) {
length = fileInputStream.read(buf);
System.out.print(new String(buf, 0, length));
}
fileInputStream.close();
}
// 使用字节流写中文。字符串之所以可以写中文,是因为借助了字符串的getBytes方法对字符串进行了编码(字符------>数字)
public static void writeTest() throws IOException {
// 找到目标文件
File file = new File("G:\\a.txt");
// 建立数据的输出通道
FileOutputStream fileOutputStream = new FileOutputStream(file);
// 准备数据,把数据写出
String str = "大家好";
byte[] buf = str.getBytes(); // 把字符串转换成字符数组
System.out.println(Arrays.toString(buf)); // [-76, -13, -68, -46, -70, -61] 为什么在记事本里显示的是“大家好”呢?因为记事本本身具有解码(数字------>字符)功能。
fileOutputStream.write(buf);
// 关闭资源
fileOutputStream.close();
}
}
2 输入字符流
---------| Reader 输入字符流的基类(抽象类)
-----------------| FileReader 读取文件的输入字符流
FileReader的用法:
- 找到目标文件
- 建立数据的输入通道
- 读取数据
- 关闭资源
public class Demo2 {
public static void main(String[] args) throws IOException {
readTest2();
}
// 使用缓冲字符数组读取文件数据
public static void readTest2() throws IOException {
// 找到目标文件
File file = new File("G:\\Demo1.java");
// 建立数据的输入通道
FileReader fileReader = new FileReader(file);
// 建立缓冲数组读取文件数据
char[] buf = new char[1024];
int length = 0;
while((length = fileReader.read(buf)) != -1) {
System.out.println(new String(buf, 0, length));
}
// 关闭资源
fileReader.close();
}
public static void readTest1() throws IOException {
// 找到目标文件
File file = new File("G:\\a.txt");
// 建立数据的输入通道
FileReader fileReader = new FileReader(file);
// 读取数据
int content = 0;
while((content = fileReader.read()) != -1) {
System.out.print((char) content);
}
// 关闭资源
fileReader.close();
}
}
3 输出字符流
---------| Writer 输出字符流的基类。抽象类
-----------------| FileWriter 向文件输出数据的输出字节流
FileWriter的使用步骤:
- 找到目标文件
- 建立数据的输出通道
- 写出数据
- 关闭资源
FileWriter要注意的事项:
- FileWriter内部维护了一个1024个字节的数组,使用FileWriter写数据时,会先写入到它内部维护的字符数组中。如果需要把数据写到硬盘上,需要调用flush或close方法,或者是等到填充满内部的字符数组后自动将数据写到硬盘上。
- 使用FileWriter时,如果目标文件不存在,那么会自动创建目标文件。
- 使用FileWriter时,如果目标文件已经存在了,那么默认情况下会先清空文件中的数据后再写入数据,如果需要在原来的基础上追加数据,需要使用 new FileWriter(File, boolean) 的构造方法,第二个参数为true。
public class Demo3 {
public static void main(String[] args) throws IOException {
writeTest();
}
public static void writeTest() throws IOException {
// 找到目标文件
File file = new File("G:\\a.txt");
// 建立数据输出通道
FileWriter fileWriter = new FileWriter(file, true);
// 准备数据,把数据写出
String data = "今天天气不错啊!!";
fileWriter.write(data);
// 刷出字符流
fileWriter.flush();
// 关闭资源
fileWriter.close();
}
}
何时使用字节流,何时使用字符流,依据是什么?
- 使用字符流的应用场景:如果是读写字符数据的时候(文本文档,java文件),则使用字符流。
- 使用字节流的应用场景:如果是读写的数据都不需要转换成字符的时候(比如图片),则使用字节流。
4 缓冲输入字符流
输入字符流:
--------| Reader 所有输入字符流的基类。抽象类
---------------| FileReader 读取文件字符串的输入字符流
---------------| BufferedReader 缓冲输入字符流。缓冲输入字符流的目的是为了提高读取文件字符的效率和拓展了FileReader的功能。其实该类内部也维护了一个字符数组。
注意:缓冲流都不具备读写数据的能力。
BufferedReader的使用步骤:
- 找到目标文件
- 建立数据的输入通道
- 读取数据
- 关闭资源
public class Demo1 {
public static void main(String[] args) throws IOException {
//readTest1();
// 调用自己的ReadLine方法
File file = new File("G:\\Demo1.java");
FileReader fileReader = new FileReader(file);
String line = null;
while((line = myReadLine(fileReader)) != null) {
System.out.println(line);
}
}
// 自己实现ReadLine方法
public static String myReadLine(FileReader fileReader) throws IOException {
// 创建一个字符串缓冲类
StringBuilder sb = new StringBuilder(); // 主要用于存储读取到的数据
int content = 0;
while((content = fileReader.read()) != -1) {
if(content == '\r') {
continue;
} else if(content == '\n') {
break;
} else {
// 普通字符
sb.append((char) content);
}
}
// 读到文件末尾时停止
if(content == -1) {
return null;
}
return sb.toString();
}
public static void readTest1() throws IOException {
// 找到目标文件
File file = new File("G:\\a.txt");
// 建立数据的输入通道
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
// 读取数据
/*
int content = bufferedReader.read(); // 读到了一个字符。读到的字符也是从BufferedReader内部的字符数组中获取到的,所以效率高。
System.out.println((char) content);
*/
// 使用BufferedReader拓展的功能 readLine() 一次读取一行文本,如果读到文件的末尾就会返回null。
String line = null;
while((line = bufferedReader.readLine()) != null) { // 虽然readLine每次读取一行数据,但是返回的数据是不包含\r\n的。
System.out.println(Arrays.toString(line.getBytes()));
}
// 关闭资源
bufferedReader.close();
}
}
5 缓冲输出字符流
输出字符流:
---------| Writer 所有输出字符流的基类。抽象类
----------------| FileWriter 向文件输出字符数据的输出字符流。内部维护了一个1024个字节的字符数组
----------------| BufferedWriter 缓冲输出字符流。作用:提高FileWriter写数据的效率和拓展FileWriter的功能-----> newLine()。
BufferedWriter要注意的事项:
- BufferWriter内部维护了一个8192个字节的字符数组,还有一个拓展功能,其他和FileWriter一样!
BufferedWriter的使用步骤?
- 找到目标文件
- 建立数据的输出通道
- 建立缓冲输出流对象
- 写出数据
- 关闭资源
public class Demo2 {
public static void main(String[] args) throws IOException {
// 找到目标文件
File file = new File("G:\\a.txt");
// 建立数据的输出通道
FileWriter fileWriter = new FileWriter(file);
// 建立缓冲输出流对象
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
// 写出数据
bufferedWriter.write("你们好!!");
bufferedWriter.newLine(); // newLine() 换行。实际上就是向文件输出\r\n。
bufferedWriter.write("你们好!!");
// 刷出字符流
bufferedWriter.flush();
// 关闭资源
// bufferedWriter.close();
}
}