IO流操作大集合

本文详细介绍了Java中的文件流、字节流和字符流的区别与操作,包括写入、读取、拷贝文件的方法,以及字节缓冲流、字符缓冲流的应用。此外,还涵盖了序列化流(如ObjectOutputStream和ObjectInputStream)用于对象持久化和反序列化的技巧,以及打印流(PrintStream和PrintWriter)的特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、分类

File只能对文件进行处理,如果想要处理文件里的内容,则要使用文件流。

文件流可分为字符和字节流:

  • 字节流(可读写任何格式的文件)
    • inputStream(抽象父类)
      • FileInputStream
    • outputStream(抽象父类)
      • FileOutputStream
  • 字符流(可续写记事本打开看得懂的文件)
    • Reader(抽象父类)
      • FileReader
    • Writer(抽象父类)
      • FileWriter

2、字节流具体操作

写文件

  1. 各个操作系统的换行符不一样,Mac:\r Windows: \r\n Linux:\n
FileOutputStream fos = new FileOutputStream("src/test/java/test.txt",true);
  //把要写入的东西放在数组里
  String str = "我要写入文件的东西";
  byte[] bytes = str.getBytes();
  fos.write(bytes);
  fos.close();

读文件

  1. 读到末位文件,返回的是-1
  2. fis.read()执行一次,相当于移动一次光标,注意不要重复读
FileInputStream fis = new FileInputStream("src/test/java/test.txt");
  int b;
  while ((b = fis.read()) != -1){
    System.out.print((char)b);
  }
  fis.close();

拷贝文件

边读边写,一次读写一个字节(速度极慢)

FileInputStream fis = new FileInputStream("src/test/java/test.txt");
        FileOutputStream fos = new FileOutputStream("src/test/java/test1.txt");
        int b ;
        while ((b = fis.read()) != -1){
            fos.write(b);
        }
        fos.close();
        fis.close();

一次读写多个字节数据,快

  1. 读取的时候,可以一次读取一个字节数组的长度
  2. 写入的时候,使用fos.write(bytes,0,len)的写入方法,表示从bytes数组中的0下标位置向后,写len长度的字节,而len长度表示这次我读取的字节数,所以最后一次读取的时候不会出现错误,多写(因为读了几个就写几个)。
FileInputStream fis = new FileInputStream("src/test/java/test.txt");
FileOutputStream fos = new FileOutputStream("src/test/java/test1.txt");
  int len ;
  byte[] bytes = new byte[2];
  while ((len = fis.read(bytes)) != -1){
    fos.write(bytes,0,len);
  }
  fos.close();
  fis.close();

在这里插入图片描述

3、字符流具体操作

读文件

  1. 一次读取char[2]哥字符的数组,读完以后存在chars中,len表示这次读取了几个字符
FileReader fileReader = new FileReader("src/test/java/test.txt");
  int len ;
  char[] chars = new  char[2];
  while ((len = fileReader.read(chars)) != -1){
      System.out.print(chars);
  }
  fileReader.close();

写文件

FileWriter fileWriter = new FileWriter("src/test/java/test.txt",true);
String str = "我要追加的字符串";
fileWriter.write(str);
fileWriter.write(str.toCharArray());
fileWriter.close();

原理

字节流没有缓冲区

读取时候的缓冲区

字符流存在一个缓冲区,第一次读的时候会尽可能的多读一些数据(8192长度),存放在缓冲区,然后先从缓冲区拿,拿完了再向文件中取。

写入时候的缓冲区

字符流在写入的时候,其实是写入到一个缓冲区中,缓冲区存满了才往硬盘里导入,可以使用flush()方法刷新缓冲区

4、缓冲流

高级流是对基本流做了一个包装,底层真正读写数据的其实还是基本流。

高级流的构造函数都要拿基本流作为传入参数,来构造

在这里插入图片描述

缓冲流(高效)

在这里插入图片描述

字节缓冲流

使用缓冲流来拷贝文件

  1. 使用方法其实还是一样的
  2. 不用关闭基本流
  3. 之所以快,是因为它节省了和硬盘打交道的时间(一次读很多),读完以后放到缓冲区中(缓冲区在内存中,搬运速度就很快)

在这里插入图片描述

字符缓冲流

在这里插入图片描述

字符缓冲读取文件

在这里插入图片描述

字符缓冲写入文件

在这里插入图片描述

5、转换流

字符流和字节流之间的桥梁。可以相互转换

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

6、序列化流

在这里插入图片描述

在这里插入图片描述

将对象写入文件中

  1. 构造函数里要传入基本流FileOutputStream
  2. 对象需要有Serializable接口
Student student = new Student();
student.setName("张三");
student.setAge(18);

ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("src/test/java/test.txt"));
objectOutputStream.writeObject(student);
objectOutputStream.close();

读取文件中的对象

ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("src/test/java/test.txt"));
Object o = objectInputStream.readObject();
System.out.println(o);
objectInputStream.close();

原理

序列化以后会的到版本号,不相同的话反序列化会报错。

可以自己手动在对象中定义版本号,名字不能改!一定要用这个名字!

在这里插入图片描述

  • 如果有成员变量不想序列化,就在前面加transient

在这里插入图片描述

如果文件中有多个对象怎么办呢?

写入多个对象

在这里插入图片描述

读取多个对象

一次 readObject() 只能读取一个对象,我们一般都把对象放在一个list当中,直接读取这个list

在这里插入图片描述

7、打印流

打印流不能读,只能写

  • 字节打印流:PrintStream
  • 字符打印流:PrintWriter
  • 有三个特点:
    • 只有写,没有读
    • 有特有的方法,可以把数据原样写出
    • 特有的写出方法可以实现自动刷新,自动换行(打印一次数据=写出+换行+刷新)

在这里插入图片描述

字节打印流

无缓冲区

在这里插入图片描述

PrintStream printStream = new PrintStream(new FileOutputStream("src/test/java/test.txt"));
printStream.println(97);
printStream.println(true);
printStream.close();

字符打印流

有缓冲区,想刷新要自动开启

在这里插入图片描述

PrintWriter printWriter = new PrintWriter(new FileWriter("src/test/java/test.txt"));
printWriter.println("wdafawdaw");
printWriter.close();

其实用的就是打印流

System.out.println();

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值