Java IO基础知识总结

IO流简介

IO即Input/Output,IO是实现输入和输出的基础,可以方便的实现数据的输入和输出。

  1. 将数据输出到外部存储的过程叫数据输出。
    输出流
  2. 将数据输入到计算机内存的过程叫数据输入。
    输入流

IO流的分类

按照不同的分类方式,可以把流分为不同的类型。常用的分类有三种:

  1. 按照流的流向分,可以分为输入流和输出流。
    • 输入流: 只能从中读取数据,而不能向其写入数据。
    • 输出流:只能向其写入数据,而不能向其读取数据。
  2. 按操作单元划分,可以分为字符流和字节流。
  3. 按流的角色划分可以分为节点流和处理流。

字节输入输出流

字节输入流(InputStream)常用方法

  • read:返回输入流下一个节点的数据。返回的值介于0255之间。如果未读取到数据,则代码返回-1,表示文件结束。
  • read(byte b[]):从输入流中读取一些字节存储到数组b中,从零开始读取,最多读取到数组b的长度。
  • read(byte b[], int off, int len) :读取一些字节存储到数组b中,从off位读取到len
  • skip(long n):忽略输入流中的n个字节,返回实际忽略的字节数。
  • available() :返回输入流中可以读取的字节数。
  • close() :关闭输入流释放相关的系统资源。

字节输出流(OutStream)常用方法

  • write(int b) :将特定字节写入输出流。
  • write(byte b[ ]) : 将b数组的内容写到输出流中。
  • write(byte[] b, int off, int len) : 将b数组中从off到off+len的内容写到输出流中。
  • flush() :刷新此输出流并强制写出所有缓冲的输出字节。
  • close() :关闭输出流释放相关的系统资源。

数据流

DataInputStream用于读取指定类型数据,不能单独使用,必须结合 FileInputStream ,注意格式必须严格准守,例如:

	/**
     * 注意读写顺序必须保持一致
     *
     */
    public static void main(String[] args) throws IOException {

            FileOutputStream fileOutputStream = new FileOutputStream("file.txt");
            DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);

            dataOutputStream.writeBoolean(true);
            dataOutputStream.writeInt(9527);
            dataOutputStream.writeShort(2);
            dataOutputStream.writeDouble(9.527);

            FileInputStream fileInputStream = new FileInputStream("file.txt");
            DataInputStream dataInputStream = new DataInputStream(fileInputStream);
            System.out.println(dataInputStream.readBoolean());
            System.out.println(dataInputStream.readInt());
            System.out.println(dataInputStream.readShort());
            System.out.println(dataInputStream.readDouble());

    }

对象流

ObjectInputStream用于将文件内容反序列化,ObjectOutputStream 用于将对象写入文件中(序列化)

 public static void main(String[] args) throws IOException {
        Person person = new Person();
        person.setName("Zayton Squid");
        person.setAge(25);
        person.setSex("male");
        person.setArea("shenzhen");
        ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(Paths.get("file.txt")));
        oos.writeObject(person);
        System.out.println(person);
        try (ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(Paths.get("file.txt")))) {
            Person person1 = (Person) ois.readObject();
            System.out.println(person1);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

字符流

字符流是由JVM将字节流转换而成的,以字符形式读取或写入数据,这个过程比较耗时,且不设置编码类型容易出现乱码。常见的编码有:

  • UTF8:英文一个字节,一个中文占3个字节。
  • unicode:无论中文英文都占2个字节。
  • GBK:一个英文1个字节,中文2个字节。

字符输入流(Reader)常用方法

  • read() : 从输入流读取一个字符。
  • read(char[] cbuf) : 从输入流中读取一些字节存储到数组b中,从零开始读取,最多读取到数组cbuf的长度 。
  • read(char[] cbuf, int off, int len) :读取一些字节存储到数组cbuf中,从off位读取到len位。
  • skip(long n) :忽略输入流中的n个字节,返回实际忽略的字节数。
  • close() : 关闭输入流并释放相关的系统资源。

示例代码:

 public static void main(String[] args) {

        try (FileReader fileReader = new FileReader("file.txt");) {
            int content;
            //跳过的字节数 5
           fileReader.skip(5);
            while ((content = fileReader.read()) != -1) {
                System.out.print((char) content);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

字符输出流(Writer)常用方法

  • write(int c) : 写入单个字符。
  • write(char[] cbuf) :将字符数组 cbuf的内容全部写到输出流。
  • write(char[] cbuf, int off, int len) :将字符数组 cbuf的内容从off到off+len写到cbuf中。
  • write(String str) :写入字符串,等价于 write(str, 0, str.length())
  • write(String str, int off, int len) :在write(String str) 方法的基础上增加了 off 参数(偏移量)和 len 参数(要读取的最大字符数)。
  • append(CharSequence csq) :将指定的字符序列附加到指定的 Writer 对象并返回该 Writer 对象。
  • append(char c) :将指定的字符附加到指定的 Writer 对象并返回该 Writer 对象。
  • flush() :刷新此输出流并强制写出所有缓冲的输出字符。
  • close():关闭输出流释放相关的系统资源。

示例代码:

 public static void main(String[] args) {
        try (FileWriter fileWriter = new FileWriter("spring-boot/src/main/java/com/example/springboot/Io/file.txt")) {
            fileWriter.write("Zayton Squid");
            fileWriter.write("Zayton Squid", 0, "Zayton Squid".length());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

字节缓冲流

BufferedInputStream(字节缓冲输入流)

BufferedInputStream在创建流对象时,会创建一个内置的默认大小(8192 字节)的缓冲区数组,通过缓冲区读写,避免频繁的IO操作,从而提高读写的效率;

public class BufferedInputStream extends FilterInputStream {

    private static int DEFAULT_BUFFER_SIZE = 8192;
	
	/**
     * 内置缓冲区数组
     */
    protected volatile byte buf[];
    
    // 使用默认的缓冲区大小
 	public BufferedInputStream(InputStream in) {
        this(in, DEFAULT_BUFFER_SIZE);
    }
    
	// 自定义缓冲区大小
	public BufferedInputStream(InputStream in, int size) {
        super(in);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

BufferedOutputStream(字节缓冲输出流)

BufferedOutputStream 将数据写进缓冲区,当缓冲区满或者用户调用flush()函数时,它就会将缓冲区的数据写入到输出流中,避免频繁的IO操作,从而提高读写的效率;如下源码所示

public synchronized void write(int b) throws IOException {
      if (count >= buf.length) {
            flushBuffer();
      }
        buf[count++] = (byte)b;
}

字符缓冲流

和字节缓冲流差不多,内置维护了一个字节数组作为缓冲区数组,字符流是以字符为单位将数据存到数组中

随机访问流

随机访问流支持操作偏移量灵活改动到任意位置进行读写。
示例代码:

    public static void main(String[] args) throws IOException {
        RandomAccessFile randomAccessFile = new RandomAccessFile(new File("file.txt"), "rw");
        System.out.println("读取之前的偏移量:" + randomAccessFile.getFilePointer() + ",当前读取到的字符" + (char) randomAccessFile.read() + ",读取之后的偏移量:" + randomAccessFile.getFilePointer());
        // 指针当前偏移量为 7
        randomAccessFile.seek(7);
        System.out.println("读取之前的偏移量:" + randomAccessFile.getFilePointer() + ",当前读取到的字符" + (char) randomAccessFile.read() + ",读取之后的偏移量:" + randomAccessFile.getFilePointer());
        // 从偏移量 8 的位置开始往后写入字节数据
        randomAccessFile.write(new byte[]{'A', 'B', 'C', 'D'});
    }

参考文献

Java IO基础知识总结

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值