IO流

发布时间 2023-08-08 00:10:29作者: Rover20230226
	1). 字节流
	字节输入流:InputStream
		I. FileInputStream
		II. BufferedInputStream
    字节输出流:OutputStream
    	I. FileOutputStream
    	II. BufferedOutputStream
    字节流可以复制任意文件数据,有4种方式一般采用字节缓冲流读写一个字节数组的方式
    
    2). 字符流
    字符输入流:Reader
    	I. InputStreamReader
    		FileReader
    	II. BufferedReader
    		String readLine():一次读取一行
        III. 读数据
            int read():一次读取一个字符
            int read(char[] chs):一次读取一个字符数组
    字符输出流:Writer
    	I.OutputStreamWriter
    		FileWriter
    	II.BufferedWriter
    		void newLine():写一个换行符
    		void write(String line):一次写一个字符串
        III. 写数据
            void write(int ch):一次写一个字符
            void write(char[], int index, int len):一次写一个字符数组的一部分
    子符流只能复制文本数据,有5种方式,一般采用字符缓冲流的特有功能
    
	3). 注意
		字符流中涉及到编码问题时,只能使用InputStreamReader和OutputStreamWriter

编码表

# 编码表
1. 计算机存储的信息都用二进制数表示
	存:编码
	取:解码
	编解码用的格式需相同,否则乱码
2. 字符集
	1). 一套字符集至少有一套字符编码
		例如:ASCII、GBXXX、Unicode
    2). ASCII:
		基本字符集,7位表示一个字符、共128字符
		扩展字符集,256字符
	3).GBXXX:
		小于127与原来相同,两个大于127连在一起表示汉字
# 字符流
## 对象:Input、Output为IDE,Reader、Writer为硬盘
1. 编码:
	byte[] getBytes():默认字符集存储到新的字节数组
	byte[] getBytes(String charsetName):指定字符集
2. 解码:
	String(byte[] bytes):默认字符集解码,构成新的String
	String(byte[] bytes,String charsetName):指定字符集
3. 字符流抽象基类
	Reader:字符输入流的抽象类
	Writer:字符输出流的抽象类
4. InputStreamReader、OutputStreamWriter
	从字节流到字符流的桥梁
	读写字符,并指定编码字符集(可使用平台默认)
	OutputStreamWriter (OutputStream out)
5. 字符流写数据的5种方式
	1. void write(int c)	写一个字符
	2. void write(char[] cbuf)	写入一个字符数组
	3. void write(char[] cbuf, int off, int len)	写入字符数组的一部分
	4. void write(String str)	写入一个字符串
	5. void write(String str, int off, int len)	写入一个字符串的一部分
6. 字符流读数据的2种方式
	1. int read()	一次读一个字符数据
	2. int read(char[] cbuf)	一次读一个字符数组数据
7. 字符流方法
	1. flush()	刷新流
	2. close()	关闭流,先刷新,关闭后不能再写数据
8. 字符文件的便捷类
	FileReader:读取字符文件的便捷类
		FileReader(String fileName)
	FileWriter:写入字符文件的便捷类
		FileWriter(String fileName)
    直接使用便捷类进行复制文件的读写操作
9. 字符缓冲流
	BufferedReader:
		从字符输入流读取文本,缓冲字符
	BufferedWriter:
		将文本写入字符输出流,缓冲字符
	以提供字符、数组和行的高效读取
	1). 构造方法
		I.
		BufferedReader(Reader in)	创建使用默认大小的输入缓冲区的缓冲字符输入流
		BufferedReader(Reader in, int sz)	指定大小
		II.
		BufferedWriter(Writer out)	创建使用默认大小的输出缓冲区的缓冲字符输出流
		BufferedWriter(Writer out, int sz)	创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区
	2). 字符缓冲流特有功能
		I. BufferedWriter
			void newLine():写一行 行分隔符,行分隔符字符串由系统属性定义
        II. BufferedReader
        	public String readLine():读一行文字。结果包含行的内容的字符串,不包括任何终止字符,如果流的结尾已经到达,则为null
    3). 写数据的三步骤
    	bw.write("写的内容");
    	bw.newLine();
    	bw.flush();
10. 小结:
	1). 字节流
	字节输入流:InputStream
		I. FileInputStream
		II. BufferedInputStream
    字节输出流:OutputStream
    	I. FileOutputStream
    	II. BufferedOutputStream
    字节流可以复制任意文件数据,有4种方式一般采用字节缓冲流读写一个字节数组的方式
    2). 字符流
    字符输入流:Reader
    	I. InputStreamReader
    		FileReader
    	II. BufferedReader
    		String readLine():读一行文字
        III. 读数据
            int read():一次读取一个字符
            int read(char[] chs):一次读取一个字符数组
    字符输出流:Writer
    	I.OutputStreamWriter
    		FileWriter
    	II.BufferedWriter
    		void newLine():写一个换行符
    		void write(String line):一次写一个字符串
        III. 写数据
            void write(int ch):一次写一个字符
            void write(char[], int index, int len):一次写一个字符数组的一部分
    子符流只能复制文本数据,有5种方式,一般采用字符缓冲流的特有功能
	3). 注意
		字符流中涉及到编码问题时,只能使用InputStreamReader和OutputStreamWriter

字节流、字符流的相关应用

# 字节流、字符流的相关应用

## 复制单级目录
1. 创建数据源目录File对象,路径是E:\\itcast
	new File
2. 获取数据源目录File对象的名称(cast)
	getName()方法
3. 创建目的地目录File对象,路径名是模块名+itcast组成
	new File
4. 判断目的地目录对应的File是否存在,如果不存在,就创建
	判断:exixts()方法
	创建:mkdir方法
5. 获取数据源目录下所有文件的File数组
	listFiles()方法
6. 遍历File数组,得到每一个File对象(数据源文件)
	1). 增强for遍历
	2). 获取数据源文件File对象的名称  getName()方法
	3). 创建目的地文件File对象  new File
	4). 复制文件  copyFile(srcFile, destFile)自定义方法
7. copyFile()自定义方法
	new BufferedInputStream
	new BufferedOutputStream
	通过字符数组写

## 复制多级目录
1. 创建数据源File对象
	new File
2. 创建目的地File对象
	new File
3. 复制文件夹  copyFolder(srcFile, destFile)自定义方法
4. copyFolder()自定义方法
	1). 判断数据源File是否是目录
    if
		I. 在目的地下创建和数据源File名称一样的目录
			getName()
			new File
        II. 判断是否存在  exists()方法
        III. 获取数据源File下所有文件或目录的File数组  listFiles()方法
        IV. 遍历该File数组,得到每一个File对象
        	增强for
        	copyFolder()递归
    else
    	I. 直接复制,用字节流
    		new File
    		copyFile()

## 复制文件的异常处理
1. try...catch...finally的做法
	try {
		可能出现异常的代码;
	} catch (异常类名 变量名) {
		异常的处理代码;
	} finally {
		执行所有清楚操作;
	}
2. JDK7改进方案(自动释放资源)
	try(定义流对象) {
		可能出现异常的代码;
	} catch (异常类名 变量名) {
		异常的处理代码;
	}
3. JDK9改进方案(自动释放资源)
	定义输入流对象;
	定义输出流对象;
	try(输入流对象;输出流对象) {
		可能出现异常的代码;
	} catch (异常类名 变量名) {
		异常的处理代码
	}

特殊操作流

# 特殊操作流

## 标准输入流(字节流)
public static final InputStream in:标准输入流。
通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
1. 定义
	InputStream is = System.in;
2. 字节流转换为字符流
	转换流
	InputStreamReader isr = new InputStreamReader(is);
	1). 问题
		字符流能不能够实现一次读取一行数据呢?
			可以
        但是,一次读取一行数据的方法是字符缓冲输入流的特有方法
    BufferedReader br = new BufferedReader(isr);
3. 三合一
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

## 标准输出流
public static final PrintStream out:标准输出流。
通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
1. 定义
	PrintStream ps = System.out;
2. System.out的本质是一个字节输出流
	PrintStream类有的方法,System.out都可以使用

打印流

# 打印流
	只负责输出数据,不负责读取数据
	有自己的特有方法
## 字节打印流
PrintStream(String fileName):使用指定的文件名创建新的打印流
使用继承父类的方法写数据,查看的时候会转码;
使用自己的特有方法写数据,查看的数据原样输出。
1. 字节输出流有的方法
	ps.write(97);  // a
2. 特有方法
	ps.print(97);  // 97
	ps.println();  // 换行
## 字符打印流 PrintWriter
1. 构造方法
	PrintWriter (String fileName)
		使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新
    PrintWriter (Writer out, boolean autoFlush)
    	创建一个新的PrintWriter
    	out:字符输出流
    	auto:一个布尔值,如果为真,则println、printf、或format方法将刷新缓冲区
## 对象序列流
对象序列流:就是将对象保存到磁盘中,或者在网络中传输对象
	这种机制就是使用一个字符序列表示一个对象,该字符序列包含:对象的类型、对象的数据和对象中存储的属性等信息,字节序列写到文件之后,相当于文件中持久保存了一个对象的信息。
	反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。
1. 对象序列化流
	ObjectOutputStream
		将Java对象的原始数据类型和图形写入OutputStream。
		可以使用ObjectInputStream读取(重构)对象。
		可以通过使用流的文件来实现对象的持久存储。
		如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象。
    1). 构造方法
    	ObjectOutputStream(OutputStream out)
    		创建一个写入指定的OutputStream的ObjectOutputStream
    2). 序列化对象的方法
    	void writeObject(Object obj)
    		将指定的对象写入ObjectOutputStream
    3). 不可序列化异常:NotSerializableException
    	抛出一个实例需要一个Serializable接口。
    	序列化运行时或实例的类可能会抛出此异常
    4). Serializable(标识接口)
    	I. 类的序列化由实现java.io.Serializable接口的类启用。
    		不实现此接口的类将不会使任何状态序列化或反序列化。
    	II. 可序列化类的所有子类型都是可序列化的。
    		序列化接口没有方法或字段,仅用于标识可串行化的语义。
    5). 注意
    	I. 一个对象要想被序列化,该对象所属的类必须必须实现Serializable接口
    	II. Serializable是一个标记接口,实现该接口,不需要重写任何方法
## 反对象序列流
2. 对象反序列化流
	ObjectInputStream