15_IO流

IO (位于 java.io 包中)

一、概念
  1. 流:数据在内存和其他存储设备传输的通道、管道。【理解】

  2. 流的分类:【面试内容】

    (1) 按照方向分:[以JVM内存为参照物]

    ​ a. 输入流:将 [其他存储设备]中数据读入到[JVM内存]中 。->读

    ​ b. 输出流:将[JVM内存]中数据写入到[其他存储设备]中。->写

    (2) 按照单位分:

    ​ a. 字节流:以字节为传输单位,可以用于操作所有类型的文件。

    ​ b. 字符流:以字符为传输单位,可以用于操作文本类型的文件。

    ​ 文本文件:只要能以记事本打开,并且不丢失原有文件内容的文件。

    ​ 例如: .txt / .java / .c / .html 等

    ​ .class / .ppt /.mp3等文件不是文本文件。

    (3) 按照功能分:

    ​ a. 节点流:只具有基本的读写功能。

    ​ b. 过滤流:在节点流的基础上,增强读写功能。

二、字节流
  1. 字节流的父类:(父类为抽象类)

    (1) InputStream:字节输入流 —》读操作(read)

    (2) OutputStream:字节输出流 --》写操作(write)

  2. 字节节点流【开发应用重点】

    (1) FileOutputStream:文件字节输出流

    ​ 常用的构造方法:

    ​ a. FileOutputStream fos = new FileOutputStream(“E:/test/a.txt”);

    ​ I. 参数:代表操作文件的路径: “E:/test/a.txt” 或是"E: \ \test \ \ a.txt"

    ​ II. 绝对路径:盘符:/ 文件夹 / 文件

    ​ III. 注意:如果指定文件不存在,则系统默认创建新的文件,但是如果指定文件夹不存在,则报错,错

    ​ 误信息为:java.io.FileNotFoundException: (系统找不到指定的路径。)

    ​ b. FileOutputStream fos = new FileOutputStream(“a.txt”);

    ​ I. 相对路径:默认在项目的根目录下查找所需要的文件,有直接用,如果指定文件不存在,则系统默

    ​ 认创建 。

    ​ c. FileOutputStream fos = new FileOutputStream(“file/c.txt”,false);

    ​ I. 第一个参数:指定操作文件路径

    ​ II. 第二个参数:boolean类型,是否在原有文件内容基础上进行追加,true-追加;false-覆盖

    ​ 常用方法:

    ​ a. void write(int n):将单个字节写入到文件中

    ​ b. void write(byte[] bs):将多个字节写入到文件中

    ​ c. void write(byte[] bs,int off,int len):将bs数组中的部分内容写入到文件中,起始下标为 off,写入的个

    ​ 数为len.

    ​ d. void close() : 代表关闭资源。

    (2) FileInputStream : 文件字节输入流

    ​ 常用的构造方法:

    ​ a. FileInputStream fis = new FileInputStream(“file/d.txt”);

    ​ I. 参数:代表操作文件的路径及文件名,但是如果指定的文件找不到,则系统不会默认创建,直接报

    ​ 错,错误信息为:java.io.FileNotFoundException: (系统找不到指定的文件。)

    ​ 常用的方法:

    ​ a. int read() : 一次性从文件中读取一个字节的内容,读取的内容作为返回值返回,如果达到文件的尾

    ​ 部,则返回-1。

    ​ 开发应用:将文件的内容进行全部读取。

    ​ while(true){

    ​ int n = fis.read();

    ​ if (n==-1) break;

    ​ // 基于 n 进行内容操作

    ​ System.out.println((char)n);

    ​ }

    ​ b. int read(byte[] bs):从文件中一次性读取多个字节内容,读取的内容自动存储在bs数组中,返回值

    ​ 代表实际读取的字节数,如果达到文件的尾部,则返回-1.

    ​ c. int read(byte[] bs,int off,int len):从文件中一次性读取多个字节内容,读取的内容自动存储在bs数组

    ​ 中(存储的起始下标为off),一次性读取的字节个数为 len ,如果达到文件的尾部,则返回-1.

    ​ 思考:如何实现文件拷贝?—》文件的上传与下载的实现原理。

  3. 字节过滤流

    (1) BufferedInputStream/ BufferedOutputStream

    ​ a. 缓冲流,提高IO读写效率,减少访问磁盘的次数

    ​ b. 缓冲流增强了缓冲区,将缓冲的内容一次性写入到文件中,可以调用 flush方法,或是close方法。

    ​ flush方法是将缓冲区的内容一次性的写入到文件中,同时缓冲清空,流可以继续使用;

    ​ 但是close方法是关闭流的同时调用的flush方法,清空缓冲区的同时将缓冲的内容一次性写入文件中,

    ​ 流不能继续被使用。

    ​ 注意:当缓冲区满的时候,自动将缓冲区的内容一次性的写入到文件中。

    (2) DataOutputStream/DataInputStream

    ​ a. 用于操作8种基本类型的数据

    ​ b. writeByte(形式参数)/ writeShort(参数)/wirteInt(参数)/…

    ​ readByte()/readShort()/readInt()/…

    (3) ObjectOutputStream/ObjectInputStream

    ​ a. 增强了缓冲区

    ​ b. 增强了操作8种基本数据类型的功能

    ​ c. 增强了操作对象的功能。

    ​ writeObject(Object obj):将对象写入到文件中

    ​ Object readObject() : 从文件中读取对象。

    ​ d. 对象序列化:将对象放在流上进行传输的过程被称为对象序列化。【重点】

    ​ I. 对象序列化的要求:参与对象序列化的对象对应的类必须实现java.io.Serializable 接口(标记性接口)

    ​ 否则运行报错,错误信息为: java.io.NotSerializableException(不可序列化异常) 【重点】

    ​ II. 文件达到尾部的标记:java.io.EOFException

    ​ III. 被 transient修饰的属性不参与对象序列化 【重点】

    ​ Iv. 如果参与对象序列化的对象中有自定义类型的属性,则自定类型的属性对应的类也必须实现

    ​ java.io.Serializable接口,否则运行报错,为不可序列化的异常。

    ​ V. 集合对应实现了创建的对象可以参与对象序列化,因为实现类实现java.io.Serializable接口;

    ​ 但是如果集合中存储的是自定义类型的对象,则自顶类型的对象对应 的类也需要实现

    ​ java.io.Serializable接口。

三、字符编码【理解】
  1. 常见的编码方式:

    (1) ISO8859-1 西欧编码,底层占用1个字节

    (2) GBK 简体中文,2万汉字

    ​ GB2312 简体中文,6000多常用汉字

    ​ GB18030 简体中文,7万左右的中国符号

    ​ 注意: GBK/GB2312/GB18030相互兼容。

    (3) Big5 繁体中文

    (4) UTF-8 万国码,底层采用动态字节数存储,每一个字符存储空间为1~3字节;

    ​ 汉字:2~3字节

  2. 编码和解码

    (1) 编码:字符对应十进制转换为二进制的过程

    (2) 解码:二进制转换为对应的十进制从而转换为与之对应的字符的过程。

    ​ 注意:编码方式和解码方式必须统一,否则会出现乱码。

四、字符流
  1. 字符流父类:(抽象类)

    (1) Reader:字符输入流 --》读操作

    (2) Writer: 字符输出流 --》写操作

  2. 字符流的节点流

    (1) FileWriter:文件字符输出流

    ​ 常用的构造方法:

    ​ FileWriter fw = new FileWriter(“file/a.txt”);

    ​ 注意:参数代表指定文件的路径及文件名,写法等同于 FileOutputStream路径的写法。

    ​ 常用功能方法:

    ​ ① void write(int n): 将单个字符写入到文件中。

    ​ ② void write(String str):将多个字符一次性写入到文件中

    ​ ③ void write(char[] cs):将 cs数组中所有字符内容一次性写入到文件中

    (2) FileReader:文件字符输入流

    ​ 常用构造方法:

    ​ FileReader fr = new FileReader(“file/a.txt”);

    ​ 常用功能方法:

    ​ ① int read():一次读取一个字符内容,将读取的字符内容存储在返回值,达到文件尾部,则返回-1。

    ​ ② int read(char[] cs):一次性读取多个字符的内容,将读取的字符内容自动存储在cs数组中,返回值

    ​ 代表实际读取的字符个数,如果达到文件的尾部,则返回-1.

  3. 字符的过滤流【重点】

    (1) BufferedReader :

    ​ 常用方法:String readLine() : 一次性读取一个文本行,如果达到文件的尾部,则返回null。

    // 1. 创建字符节点流对象	
    FileReader fr = new FileReader("file/c.txt");
    		
    // 2. 包装过滤流
    BufferedReader br = new BufferedReader(fr);
    		
    // 3. 读操作
    while(true){
        String str = br.readLine();
        if(str == null) break;
        System.out.println(str);
    }
    		
    // 4. 关闭:最外层
    br.close();
    

    (2) PrintWriter:

    ​ ① 可以操作8种基本数据类型

    ​ ② 提供了自动换行和不换行的println/print方法

    ​ println(形式参数):自动完成换行

    ​ print(形式参数):不自动换行

    ​ ③ println(Object obj)/print(Object obj):将对象的 toString方法的返回值结果写入到文件中。

    ​ 注意:写出 ObjectOutputStream中writeObject(Object ob) 方法 和 PrintWriter中println(Object obj)

    ​ 方法的区别。

    ​ 解析:ObjectOutputStream中writeObject(Object ob):将对象放入流上进行传输,要求传输的对象对

    ​ 应的类必须实现 java.io.Serializable接口,这个过程被称为对象序列化。

    ​ PrintWriter中println(Object obj):将对象的toString方法的返回值String类型的结果写入文件中,

    ​ 写入的对象对应的类没有任何要求。

  4. 字符的桥转流【开发重点】

    (1) InputStreamReader:桥转的输入流

    ​ OutputStreamWriter:桥转换的输出流

    (2) 作用:

    ​ a. 可以将字节流转换字符流,即字节流和字符流转换桥梁

    ​ b. 可以设置编解码的格式

    (3) 应用场景:需要指定编解码格式的时候,可以利用桥转流进行指定。

    (4) 使用步骤:

    ​ ① 创建字节节点流对象:FileOutputStream/FileInputStream

    ​ ② 创建桥转换流:字节流-》字符流,同时指定编解码格式

    ​ OutputStreamWriter / InputStreamReader

    ​ ③ 包装过滤流:目的增强字符流的读写操作

    ​ PrintWriter / BufferedReader

    ​ ④ 读写操作

    ​ ⑤ 关闭流:关闭最外层即可

五、File类(java.io包中)
  1. File类和IO流的区别。

    (1) IO流:对文件的内容进行操作,读取的内容或是将内容写入到文件中。

    (2) File类:对文件本身进行操作,例如:删除文件、更改文件名等。

    ​ 注意:File类本身不具有操作文件的功能,类中的方法提供了操作文件的功能。

  2. File类中常用的方法:

    (1) String getName() : 获取文件名,带有扩展名。

    (2) String getAbsolutePath(): 获取绝对路径。【重点】

    // 功能:获取文件夹中所有内容,同时进行逐一判断
    	public static void selectAllEndJava(File file){
    		// 获取文件夹中所有文件和文件夹
    		File[] fs = file.listFiles();
    		
    		// 遍历:获取每一个文件或是文件夹
    		for(File f:fs){
    			//判断是文件还是文件夹
    			if(f.isFile()){
    				// 是文件
    				// 判断文件是否 以 .java结尾
    				String name = f.getName();
    				if(name.endsWith(".java")){
    					// 打印输出 绝对路径
    					System.out.println(f.getAbsolutePath());
    				}
    			}else{
    				// 文件夹:
    				selectAllEndJava(f);// 递归
    			}
    		}
    	}
    

    IO流的总结:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gLMszokh-1594187828470)(C:\Users\HIAPAD\AppData\Roaming\Typora\typora-user-images\1566283278730.png)]

{
// 是文件
// 判断文件是否 以 .java结尾
String name = f.getName();
if(name.endsWith(".java")){
// 打印输出 绝对路径
System.out.println(f.getAbsolutePath());
}
}else{
// 文件夹:
selectAllEndJava(f);// 递归
}
}
}




IO流的总结:

[外链图片转存中...(img-gLMszokh-1594187828470)]










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值