1.流的分类
IO流按照读取方式:
- 字符流
- Reader基类
- Writer基类
- 字节流
- InputStream基类
- OutputStream基类
2.文件操作:字符流
使用FileWriter和FileReader就能实现文件的读写、拷贝
1. FileWriter
FileWriter fileWriter = new FileWriter("fileName"); //参数可以是绝对路径或相对路径
FileWriter(String fileName)构造函数:如果没有文件则创建新文件,如果已有文件,则覆盖原有文件内容
- flush():将缓冲的数据写入文件
fileWriter.write("mio");
fileWriter.flush(); //刷新
- close():刷新缓冲,关闭流
new FileWriter、flush、close都会跑出I/O异常,需要处理
2. FileReader
注意API中的重载,对于不同的参数,有不同的适用场景
FileReader fileReader = new FileReader("filewriter.txt"); //跑出FileNotFound异常
- read() :每次读入一个字符,返回值是int类型,如果读到文件末尾则返回-1
int ch = fileReader.read();
System.out.println((char)ch);
- read(char[] buf) :使用char数组来接纳读入的字符,buf起到了缓冲区的作用
char[] buf = new char[1024]; //尽量保证数组长度大于要读的长度
int num = fileReader.read(buf); //使用buf来接受读取的字符串
实战:通过FileReader和FileWriter实现文件的拷贝
养成良好的编程习惯:对于FileRead和FileWriter需要close,否则可能导致文件读写失败,我猜测原因是没有刷新缓冲区导致
3. BufferedWriter
- BufferedWriter的产生原因
- 提高字符流写入效率
BufferedWriter bufferedWriter = new BufferedWriter(Writer out); //封装Writer对象
- 配合FileWriter使用
FileWriter fileWriter = new FileWriter("buffer.txt");
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); //封装FileWriter对象
bufferedWriter.write("mio123456"); //以BufferedWriter对象代替FileWriter对象操作
bufferedWriter.flush(); //刷新缓冲区
- newLine():在文件中写入换行符(区别于\n ,这种换行符在Linux和Windows下通用)
4. BufferedReader
- readLine():以行的方式读取文本,这是相对于FileReader API更为实用的方式,返回值会过滤回车,所以需要手动调用newLine()
FileReader fileReader = new FileReader("buffer.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
String s;
while((s = bufferedReader.readLine()) != null){ //读到文件末尾的时候返回null
System.out.println(s);
}
bufferedReader.close(); //可以只关闭bufferedReader
使用BufferedWriter和BufferedReader可以实现文件的拷贝,特别注意对于换行符的处理
5. 装饰者模式
- BufferedReader是对FileReader功能的增强(提供了缓冲区功能),体现了Java中的装饰者设计模式
- 装饰者模式
- 在不改变原有代码的前提下,允许行为被扩展
- 装饰者模式比继承更加灵活
- 装饰者和被装饰者有相同的超类型(父类)
//一个不正式的Demo,被装饰者和装饰类一般继承自相同的类
class Person{ //被装饰类
public void eat(){
System.out.println("person eat rice");
}
}
class DecPerson{ //装饰类
private Person person;
DecPerson(Person person){
this.person = person;
}
public void DecEat(){
System.out.println("do some drinking");
person.eat();
System.out.println("wash hands");
}
}
6. LineNumberReader
- API:getLineNumber()方法能够返回读取的行号
FileReader fileReader = new FileReader("buffer.txt");
LineNumberReader lineNumberReader = new LineNumberReader(fileReader);
String line = null;
while((line = lineNumberReader.readLine()) != null){
System.out.println(lineNumberReader.getLineNumber() + ":" + line);
}
lineNumberReader.close();
7. InputStreamReader
有些时候处理字节需要字符流类的API,怎样将流之间关联起来呢?
将对于字节流的处理转换为对于字符流的处理
InputStream in = System.in; //获取标准输入流
InputStreamReader inputStreamReader = new InputStreamReader(in); //包装in
BufferedReader bufferedReader = new BufferedReader(inputStreamReader); //包装inputStreamReader
//--- ---
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); //简化
8. OutputStreamWriter
OutputStream out = System.out; //获取标准输出流
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(out);
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
3. 文件操作:字节流
上述的类能够处理一般的文本文件,但是涉及到图片,音频的处理时,使用字节流处理
API类比FileReader和FileWriter
1.FileOutputStream
- write()方法不需要手动刷新
void write(byte[] b); //API
FileOutputStream fileOutputStream = new FileOutputStream("stream.txt");//打开文件
fileOutputStream.write("mio".getBytes()); //字符串需要转换为字节格式
fileOutputStream.close();
2.FileInputStream
- 按字节读取文件
FileInputStream fileInputStream = new FileInputStream("stream.txt");
byte[] buf = new byte[1024]; //读时使用缓冲区
int len = 0;
while((len = fileInputStream.read(buf)) != -1){ //byte[]数组作为参数read
System.out.print(new String(buf,0,len));
}
- available():返回文件中实际可读字节数(包括 ‘\r’ ‘\n’)
- 作用:处理小文件时,确定缓冲区的大小
Demo:同时使用FileOutputStream和FileInputStream可以使用图片、媒体文件等文件的拷贝
3.BufferedOutputStream
Buffer类设计很又对称性,API同BufferedFileWriter
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("F://FictionJunction - 暁の車.mp3"));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("I://FictionJunction - 暁の車.mp3"));
int b = 0;
while((b = bufferedInputStream.read()) != -1){
bufferedOutputStream.write(b);
}
bufferedInputStream.close();
bufferedOutputStream.close();
4.BufferedInputStream
API同BufferedFileReader
Demo:使用指针和数组自己实行一个BufferedInputStream