Java IO基础知识总结

IO流简介

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

  1. 将数据输出到外部存储的过程叫数据输出。Java IO基础知识总结
  2. 将数据输入到计算机内存的过程叫数据输入。Java IO基础知识总结

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基础知识总结


原文始发于微信公众号(写代码的ZaytonSquid):Java IO基础知识总结

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/246396.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!