一、理解
1. 简单而言:流就是内存于存储设备之间传输数据的通道、管道
2. 流的分类:
(1)按方向(以jvm虚拟机为参照物)【重点】
输入流:将<存储设备>中的内容读入到<内存>中
输出流:将<内存>中内容写入到<存储设备>中
(2)按单位:
字节流:以字节为单位,可以操作所有类型的文件
字符流:以字符为单位,只能操作文本类型的文件
(3)按功能:
节点流:具有基本的读写功能
过滤流:在节点流的基础上,增加新的功能
二、字节流
1. 字节流的父类(抽象类)
(1)InputStream:字节输入流
对应的操作为读操作
功能方法:read方法
(2)OutputStream:字节输出流
对应的操作为写操作
功能方法:write方法
2. 字节流的子类-节点流
(1)FileOutputStream:文件字节输出流
a. 构造方法:
FileOutputStream fos = new FileOutputStream("D:\\test2\\a.txt");
参数:代表操作文件的路径,指定的文件夹必须存在,否则报错,错误信息为:
java.io.FileNotFoundException(文件找不到的异常);但是指定文件如果不存在,则系统默认创建一个新的
文件路径:绝对路径和相对路径
绝对路径:带有盘符的路径,例如 D:\\test2\\a.txt
相对路径:相对当前项目查找对应的路径,例如:
FileOutputStream fos = new FileOutputStream("file/a.txt");
b. 功能方法:
void write(int a):将单个字节内容写入到文件中
void close():关闭流,释放系统资源
public class TeatFileOutputStream{
public staticvoid main(String[] args)throws IOException{
// 1. 船舰文件字节输出流对象
FileOutputStream fos = new FileOutputStream("file/a.txt");
// 2. 写文件
fos.write(97);
// 3. 关闭流:释放资源
fos.close();
}
}
(2)FileInputStream:文件字节输入流
a. 构造方法
FileInputStream fos = new FileInputStream("file/a.txt");
参数:代表要读取哪一个文件中的内容;如果指定的文件不存在,则系统不会自动创建,而是抛出异常:
java.io.FileNotFoundException:file\a.txt(系统找不到指定的文件)
b. 功能方法:
int read():一次性读取一个字节,将读取的内容作为返回值进行返回,如果达到文件尾部,则返回-1
close():关闭流,释放资源
3. 字节流的子类-过滤流
(1)BufferedInputStream/BufferedOutputStream
// 1. 创建文件输入+输出流
FileInputStream fis=new FileInputStream("D:\\test\\ph.mp4"); // 读文件
BufferedInputStream bis=new BufferedInputStream(fis);
FileOutputStream fos=new FileOutputStream("file/ph_copy.mp4");
BufferedOutputStream bos=new BufferedOutputStream(fos);
// 2. 读和写
while(true){
int n=bis.read(); // 读
if(n==-1) break;
bos.write(n);
}
// 3. 关闭流
fis.close();
fos.close();
(2)过滤流:ObjectOutputStream/ObjectInputStream
a. 增强了缓冲区功能
增强了读写8中基本数据类型和字符串功能
b. 增强了读写对象的功能:readObject() 从流中读取一个对象/
writeObject(Object obj)向流中写入一个对象
c. 对象放在流上进行传输的过程成为对象序列化。对象序列化的要求:【重点】
参与对象序列化的对象对应的类,必须实现java.io.Serializable接口
transient修饰的属性,不参与对象序列化
对象序列化达到文件尾部的表示:
如果运行时抛出 jaba.io.EOFException , 代表读取的文件达到尾部
对序列化的细节:
如果对象的属性,时自定义类型的对象时,则该对象也必须是可序列化的
如果对集合进行对象序列化,必须保证该集合中的所有元素是可序列化的
三、字符流
1. 字符流的父类(抽象类):
(1)Reader:字符流输入
对应的操作为读操作
功能方法:read方法
(2)writer:字符输出流
对应的操作为写操作
功能方法:writer方法
2. 文件字符流输入/输出流
(1)FIleWriter文件字符输出流,继承writer中的方法:
publicvoid writer(int n):将单个字符写入到文件中
(2)FileReader文件字符输入流,继承Reader中的方法:
public int read():-次读取一个字符的内容
3. 字符过滤流
(1)BufferedReader:增强读取一行内容的方法
String readLine(): 一次性读取一行内容,返回值为String,达到文件尾部时,返回nu11
(2)Priterwriter:一次性写入一行内容
println(string str):将一行内容写入到文件,自动换行
print(string str):将一行内容写入到文件,不自动换行
4. 桥转换流
InputStreamReader、0utputStreamwriter
(1)字符流和字符流之间转换的通道
(2)指定编解码格式
public class TestInputStreamReader {
public static void main(string[]args)throws IOException {
//1.创建文件字节输入流对象(基础流)->不能更改文件编码格式(GBK)
FileInputStream fis = new FileInputstream("file/m.txt");
//2.创建桥转换流,指定编解码格式为“GBK”
InputStreamReader isr = new InputstreamReader(fis,"GBK");
//3.包装过滤流:增强读操作
BufferedReader br = new BufferedReader(isr);
//4.读操作
while(true){
String s= br.readLine();
if(s==nu1l) break;
System.out.println(s);
}
//5.关闭流
br.close();
}
}
package testio2;
import java.io.*;
public class TestInputstreamReader {
public static void main(string[] args){
BufferedReader br = nu11;
try {
//1.创建文件字节输入流对象(基础流)->不能更改文件编码格式(GBK)
FileInputstream fis = new FileInputstream("file/m.txt");
//2.创建桥转换流,指定编解码格式为“GBK”
InputStreamReader isr = new InputStreamReader(fis, "GBK");
//3.包装过滤流:增强读操作
br = new BufferedReader(isr);
//4.读操作
while(true){
string s = br.readLine();
if(s == nu11)break;
system.out.printin(s);
}
}catch (Exception e){
e.printstackTrace();
}finally {
if(br!=nu11){
// 5.关闭流
try {
br.close();
}catch(IOException e){
e.printstackTrace();
}
}
}
}
}