Java 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. 过滤流:在节点流的基础上,增强读写功能。
    二、字节流
  3. 字节流的父类: ( 父类为抽象类 )
    (1) InputStream:字节输入流 --- 》读操作 (read)
    (2) OutputStream:字节输出流 -- 》写操作 (write)
  4. 字节节点流【开发应用重点】
    (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.
    思考:如何实现文件拷贝?--- 》文件的上传与下载的实现原理。
  5. 字节过滤流
    (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接口。
    三、字符编码【理解】
  6. 常见的编码方式:
    (1) ISO8859-1 西欧编码,底层占用 1 个字节
    (2) GBK 简体中文, 2 万汉字
    GB2312 简体中文,6000 多常用汉字
    GB18030 简体中文,7 万左右的中国符号
    注意: GBK/GB2312/GB18030 相互兼容。
    (3) Big5 繁体中文
    (4) UTF-8 万国码,底层采用动态字节数存储,每一个字符存储空间为 1~3 字节;
    汉字: 2~3 字节
  7. 编码和解码
    (1) 编码:字符对应十进制转换为二进制的过程
    (2) 解码:二进制转换为对应的十进制从而转换为与之对应的字符的过程。
    注意:编码方式和解码方式必须统一,否则会出现乱码。
    四、字符流
  8. 字符流父类: ( 抽象类 )
    (1) Reader: 字符输入流 -- 》读操作
    (2) Writer: 字符输出流 -- 》写操作
  9. 字符流的节点流
    (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.
  10. 字符的过滤流【重点】
    (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 类型的结果写入文件中 , 写入的对象对应的类没有任何要求。
  11. 字符的桥转流【开发重点】
    (1) InputStreamReader:桥转的输入流
    OutputStreamWriter:桥转换的输出流
    (2) 作用:
    a. 可以将字节流转换字符流,即字节流和字符流转换桥梁
    b. 可以设置编解码的格式
    (3) 应用场景:需要指定编解码格式的时候,可以利用桥转流进行指定。
    (4) 使用步骤:
    ① 创建字节节点流对象:FileOutputStream/FileInputStream
    ② 创建桥转换流:字节流-》字符流,同时指定编解码格式
    OutputStreamWriter / InputStreamReader
    ③ 包装过滤流:目的增强字符流的读写操作
    PrintWriter / BufferedReader
    ④ 读写操作
    ⑤ 关闭流:关闭最外层即可
    五、 File (java.io 包中 )
  12. File 类和 IO 流的区别。
    (1) IO流:对文件的内容进行操作,读取的内容或是将内容写入到文件中。
    (2) File类:对文件本身进行操作,例如:删除文件、更改文件名等。
    注意:File类本身不具有操作文件的功能,类中的方法提供了操作文件的功能。
  13. 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 ); // 递归
    }
    }
    }
相关推荐
陈小桔8 小时前
idea中重新加载所有maven项目失败,但maven compile成功
java·maven
小学鸡!8 小时前
Spring Boot实现日志链路追踪
java·spring boot·后端
xiaogg36788 小时前
阿里云k8s1.33部署yaml和dockerfile配置文件
java·linux·kubernetes
逆光的July8 小时前
Hikari连接池
java
微风粼粼9 小时前
eclipse 导入javaweb项目,以及配置教程(傻瓜式教学)
java·ide·eclipse
番茄Salad9 小时前
Spring Boot临时解决循环依赖注入问题
java·spring boot·spring cloud
立志成为大牛的小牛9 小时前
数据结构——二十六、邻接表(王道408)
开发语言·数据结构·c++·学习·程序人生
天若有情6739 小时前
Spring MVC文件上传与下载全面详解:从原理到实战
java·spring·mvc·springmvc·javaee·multipart
祈祷苍天赐我java之术9 小时前
Redis 数据类型与使用场景
java·开发语言·前端·redis·分布式·spring·bootstrap
MediaTea10 小时前
Python 第三方库:matplotlib(科学绘图与数据可视化)
开发语言·python·信息可视化·matplotlib