一、节点流和处理流的区别和联系
- 节点流是底层流(低级流),直接和数据源相连接。
- 处理流(包装流)对节点流进行了包装,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出。
- 处理流对节点流进行了包装,使用了修饰器的设计模式,不能直接与数据源相连接。
二、处理流特点
- 性能的提高:主要以增加缓冲的方式来提高输入输出的效率。
- 操作的便捷:处理流提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便。
按字符用reader读取,writer写入,常用于文本文件(能用记事本打开的)
按字节用InputStream读取,OutputStream写入,常用于二进制文件
三、文件读取和写入
1、FileReader和FileWriter
1.1 FileReader
- new FileReader(File/String)
- read():每次读取单个字符,返回该字符,如果到文件末尾返回-1
- read(char[]):批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回-1
相关API:
- new String(char[]):将char[]转换成String
- new String(char[],off,len):将char[]的指定部分转换成String
public class readFile01 {
public static void main(String[] args) throws IOException {
String file_path = "e:\\1.txt";
FileReader fileReader = new FileReader(file_path);
int readLen = 0;
char[] buf = new char[1024];
while((readLen=fileReader.read(buf))!=-1){
System.out.println(new String(buf,0,readLen));
}
fileReader.close();
}
}
1.2 FileWriter
- new FileWriter(File/String):覆盖模式,相当于流的指针在首端
- new FileWriter(File/String,true):追加模式,相当于流的指针在尾端
- write(int):写入单个字符
- write(char):写入指定数组
- write(char[],off,len):写入指定数组的指定部分
- write (string):写入整个字符串
- write(string,off,len):写入字符串的指定部分
相关API: String类:toCharArray:将String转换成char[]
注意:FileWriter使用后,必须要关闭(close)或刷新(flush),否则写入不到指定的文件!
public class writeFile01 {
public static void main(String[] args) throws IOException {
String file_path ="e:\\2.txt";
FileWriter fileWriter = new FileWriter(file_path,true);
char[] cs = new char[]{'a','b','c'};
fileWriter.write(cs);
fileWriter.flush();
String s = "hello,world";//s.getBytes()可以转为字节数组
fileWriter.write(s,0,s.length());
fileWriter.flush();
fileWriter.close();
}
}
2、FileInputStream和FileOutputStream
和Reader和Writer类似,只不过是把char数组改为byte数组
四、缓冲流
BufferedReader和BufferedWriter
BufferedReader
public class BufferedReader_ {
public static void main(String[] args) throws IOException {
String file_path = "e:\\1.txt";
BufferedReader br = new BufferedReader(new FileReader(file_path));
String line = "";
while((line=br.readLine())!=null){
System.out.println(line);
}
br.close();
}
}
BufferedWriter
public class BufferedWriter_ {
public static void main(String[] args) throws IOException {
String file_path ="e:\\2.txt";
BufferedWriter bw = new BufferedWriter(new FileWriter(file_path));
String s = "hello,world";
bw.write(s);
bw.newLine(); //换行
bw.flush();
bw.close();
}
}
2、BufferedInputStream和BufferedOutputStream
和Reader和Writer类似,只不过是通过String.getBytes()将字符串转为字节再传输。
五、转换流
通过InputStreamReader和OutputStreamWriter从字节流转换到字符流。即使用BufferedReader包装InputStreamReader包装字节输入节点流
- InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成(转换)Reader(字符流)
- OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)
- 当处理纯文本数据时,使用字符流效率更高,并且可以有效解决中文问题,所以建议将字节流转换成字符流
- 可以在使用时指定编码格式(比如utf-8, gbk , gb2312, IS08859-1等)
public class InputStreamReader_ {
public static void main(String[] args) throws IOException {
String file_path = "e:\\1.txt";
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file_path)));
char[] cs = new char[1024];
int readLen = 0;
while((readLen=br.read(cs))!=-1){
System.out.println(new String(cs,0,readLen));
}
// 或者
String line = "";
while((line = br.readLine())!=null){
System.out.println(line);
}
br.close();
}
}
public class OutputStreamWriter_ {
public static void main(String[] args) throws IOException {
String file_path ="e:\\2.txt";
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file_path)));
bw.write("hello,world");
bw.newLine();
bw.flush();
bw.close();
}
}
六、对象流
在保存数据时,保存数据的值和数据类型(序列化)
在读取数据时,读取数据的值和数据类型(反序列化)
//注意:如果对自定义的类进行序列化,这个类必须放在序列化和反序列化都能引用的位置,
//最好放在一个公有类中,否则会导致序列不一致出错。
public class Dog implements Serializable{
private String name;
private int age;
private String country;
private String color;
public Dog(String name, int age, String country, String color) {
this.name = name;
this.age = age;
this.country = country;
this.color = color;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
", country='" + country + '\'' +
", color='" + color + '\'' +
'}';
}
}
//序列化
public class ObjectOutStream_ {
public static void main(String[] args) throws IOException {
String file_path = "e:\\data.dat";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file_path));
//序列化数据
oos.writeInt(100);
oos.writeBoolean(true);
oos.writeChar('a');
oos.writeDouble(1.5);
oos.writeUTF("hello,world");//String
oos.writeObject(new Dog("小白",10,"中国","白色"));
oos.close();
}
}
//反序列化
public class ObjectInputStream_ {
public static void main(String[] args) throws IOException, ClassNotFoundException {
String file_path = "e:\\data.dat";
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file_path));
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
System.out.println(ois.readChar());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
Object dog = ois.readObject();
Dog dog2 = (Dog) dog;
System.out.println(dog2);
ois.close();
}
}