| 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 |
| |
构造方法(字符输出流)
方法名 |
说明 |
FileWriter(File file) |
根据给定的 File 对象构造一个 FileWriter 对象 |
FileWriter(File file, boolean append)是否要覆盖之前的内容 |
根据给定的 File 对象构造一个 FileWriter 对象 |
FileWriter(String fileName) |
根据给定的文件名构造一个 FileWriter 对象 |
FileWriter(String fileName, boolean append) |
根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象 |
成员方法(字符输出流)
方法名 |
说明 |
void write(int c) |
写一个字符 |
void write(char[] cbuf) |
写入一个字符数组 |
void write(char[] cbuf, int off, int len) |
写入字符数组的一部分 |
void write(String str) |
写一个字符串 |
void write(String str, int off, int len) |
写一个字符串的一部分 |
构造方法(字符输入流)
方法名 |
说明 |
FileReader(File file) |
在给定从中读取数据的 File 的情况下创建一个新 FileReader |
FileReader(String fileName) |
在给定从中读取数据的文件名的情况下创建一个新 FileReader |
构造方法(字符输出流)
方法名 |
说明 |
int read() |
一次读一个字符数据 |
int read(char[] cbuf) |
一次读一个字符数组数据 |
字节流和字符流的区别
| # 字节流和字符流 |
| 1. 缓冲区 |
| 1). 字节输出流没有缓冲区,会先将数据直接写到硬盘上 |
| 2). 字符输出流有缓冲区,数据先放在缓冲区,不会直接写到硬盘上 |
| 2. flush方法 |
| 1). 对于字节输出流没有意义的 |
| 2). 对字符流有一点意义 |
| |
公共功能
| # 公共功能 |
| 1. close()方法 |
| 1). flush 刷新当前的流: 将缓冲区数据同步到硬盘 |
| 2). 释放资源(一旦关闭,就不能再写数据) |
| 2. flush()方法 |
| 刷新流,之后还可以继续写数据 |
| |
发现
| 1. FileOutputStream与FileWriter |
| FileOutputStream在不使用flush或close的前提下可以直接写入 |
| FileWriter则需要flush或close才可以写入内容 |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通