java 常用IO流梳理,持续更新...

定义

JavaIO流,是一种计算机用语。主要是用于处理数据的传输。

背景

I/O 流众多,在学习I/O流时,流与流之间关系理不清楚,什么场景下该选择使用什么样的流?成为了难点,因此,文本根据笔者的学习情况,梳理了常用的几种流

流的分类

按方向划分:

  • 输入流输出流

按处理的数据单位划分:

  • 字节流字符串

按功能划分:

  • 节点流处理流

四大抽象类

类定义说明
InputStream字节输入流,特点:凡是继承它的子类,类命名均以 InputStream 结尾,都是字节输入流
OutputStream字节输出流,特点:凡是继承它的子类,类命名均以 OutputStream 结尾,都是字节输出流
Reader字符输入流,特点:凡是继承它的子类,类命名均以 Reader 结尾 ,都是字符输入流
Writer字符输出流,特点:凡是继承它的子类,类命名均以 Writer 结尾,都是字符输出流

生活场景类比计算机输入输出流操作

抽水机抽水到水塔的A区:相当于输入流 InputStram
水塔对水进行消毒、过滤、净化后装入水塔B区:相对于对输入流里的数据写入到输出流
水塔将B区的净化水供给到居民家里:相当于将输出流进行输出
在这里插入图片描述

浅谈文件拷贝过程内存中的对象

在这里插入图片描述

常用流说明

字节流

FileInputStream 对文件操作的字节输入流
  • 构造方法
构造器方法说明
FileInputStream(File file)有参构造器,传入 File 对象
FileInputStream(String name)有参构造器,传入文件的路径(含文件名)
  • 常用方法
返回类型方法方法说明
intread()从该文件字节输入流中读取 下一个字节,并返回 该字节 对应的 整型数值,且游标自动指向下一个字节的位置
intread(byte[] b)从该文件字节输入流读取最多 b.length 个字节的数据放入 字节数组b,并返回读取到的字节个数
intread(byte[] b, int off, int len)从该文件字节输入流读取最多 len 个字节的数据放入 字节数组b,并返回读取到的字节个数
voidclose()关闭此文件字节输入流并释放与流相关联的任何系统资源
  • 代码演示
package com.wei.java.basic.io;

import java.io.FileInputStream;

/**
 * @author: wei
 * @date 2022/5/7 10:36
 * 说明:
 **/
public class FileInputStream_my {
    public static void main(String[] args) {
        String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
        try (
                FileInputStream fis = new FileInputStream(filePath);
        ) {
            // .read() 读取一个字节,并返回
            int byteInt = fis.read();
            System.out.println(byteInt +" -> " + (char)byteInt);

            // .read(bytes),每次只从流中读取2个字节,UTF-8编码,一个汉字占3个字节
            byte[] bytes = new byte[2];
            int len;
            while ((len = fis.read(bytes)) != -1){
                // new String() 强行将一个汉字的 2 个字节转为字符串,会乱码
                System.out.print(new String(bytes));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

FileOutputStream 对文件操作的字节输出流
  • 构造方法
构造器方法说明
FileOutputStream(File file)有参构造器,传入 File 对象,创建文件输出流以写入到指定的 File对象表示的文件
FileOutputStream(File file, boolean append)有参构造器,传入 File 对象,创建文件输出流以写入到指定的 File对象表示的文件,append参数控制覆盖或追加数据到文件,true-追加,false-覆盖,默认false
FileOutputStream(String name)有参构造器,传入文件的路径+文件名,将数据输出到指定的文件
FileOutputStream(String name, boolean append)有参构造器,传入文件的路径+文件名,将数据输出到指定的文件,append参数控制覆盖或追加数据到文件,true-追加,false-覆盖,默认false
  • 常用方法
返回类型方法方法说明
voidwrite(int b)将一个字节整型数字,写入该文件字节输出流
voidwrite(byte[] b)b.length 个字节从 字节数组b 写入该文件字节输出流
voidwrite(byte[] b, int off, int len)字节数组b中,从 偏移量off 开始的 len个字节 数据,写入到该文件字节输出流
voidclose()关闭此文件字节输出流并释放与流相关联的任何系统资源,不需要close(),数据也会输出到磁盘
  • 代码演示
package com.wei.java.basic.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;

/**
 * @author: wei
 * @date 2022/5/7 10:36
 * 说明:
 **/
public class FileOutputStream_my {
    public static void main(String[] args) {
        String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
        String outFilePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\out_01.txt";
        try (
                FileInputStream fis = new FileInputStream(filePath);
                FileOutputStream fos = new FileOutputStream(outFilePath);
        ) {
            // fos.write(bytes, 0, len);  不需要flush(),数据也写到磁盘了
            byte[] bytes = new byte[2]; // 数组设2,只为调试
            int len;
            while ((len = fis.read(bytes)) != -1) {
                fos.write(bytes, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

ByteArrayInputStream 对字节数组操作的字节输入流
  • 构造方法
构造器方法说明
ByteArrayInputStream(byte[] buf)有参构造, 传入字节数组
  • 常用方法
返回类型方法方法说明
intread()从该字节数组输入流中读取 下一个字节,并返回 该字节 对应的 整型数值
intread(byte[] b)从该字节数组输入流读取最多 b.length 个字节的数据放入 字节数组b,并返回读取到的字节个数
intread(byte[] b, int off, int len)从该字节数组输入流读取最多 len 个字节的数据放入 字节数组b,并返回读取到的字节个数
voidclose()关闭 ByteArrayInputStream没有任何效果,该流中的方法仍可以在流关闭后调用,而不生成IOException
  • 代码演示
package com.wei.java.basic.io;

import java.io.ByteArrayInputStream;
import java.io.IOException;

/**
 * @author: wei
 * @date 2022/5/8 13:38
 * 说明:
 **/
public class ByteArrayInputStream_my {
    public static void main(String[] args) throws IOException {
        byte[] bytes = "wddd".getBytes();
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        int byteInt = bais.read();
        System.out.println((char)byteInt);
        // close() 不会起作用
        bais.close();

        int byteInt2 = bais.read();
        System.out.println((char)byteInt2);

        byte[] buff = new byte[2];
        int read = bais.read(buff);
        System.out.println(new String(buff));
    }
}

ByteArrayOutputStream 对字节数组操作的字节输出流
  • 构造方法
构造器方法说明
ByteArrayOutputStream()无参构造器
  • 常用方法
返回类型方法方法说明
voidwrite(int b)将一个字节整型数字,写入该字节数组输出流
voidwrite(byte[] b, int off, int len)字节数组b中,从 偏移量off 开始的 len个字节 数据,写入到该字节数组输出流
byte[]toByteArray()将字节数组输出流中的数据,转为新的字节数组,并返回该新的字节数组的完整数据
StringtoString(String charsetName)将字节数组输出流中的数据转换为字符串,并指定编码类型
voidclose()关闭 ByteArrayOutputStream 没有任何效果,该流中的方法可以在流关闭后调用,而不生成IOException
  • 代码演示
package com.wei.java.basic.io;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * @author: wei
 * @date 2022/5/8 13:38
 * 说明:
 **/
public class ByteArrayOutputStream_my {
    public static void main(String[] args) throws IOException {
        byte[] bytes = "qwertyuiopa我的观点".getBytes();
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        int byteInt = bais.read();
        System.out.println((char) byteInt);

        // close() 不会起作用
        bais.close();

        byte[] buff = new byte[2];
        int len;
        while ((len = bais.read(buff)) != -1) {
            baos.write(buff, 0, len);
        }

        // close() 也是不起作用的
        baos.close();
        baos.flush();

        // 转数组
        byte[] resultBytes = baos.toByteArray();
        System.out.println(new String(resultBytes));
        // 转字符串
        String resultStr = baos.toString("utf-8");
        System.out.println(resultStr);
    }
}

BufferedInputStream 带缓冲区的字节输入流
  • 构造方法
构造器方法说明
BufferedInputStream(InputStream in)有参构造器,传入 InputStream 对象
  • 常用方法
返回类型方法方法说明
intread()从该带缓冲区的字节输入流中读取 下一个字节,并返回 该字节 对应的 整型数值
intread(byte[] b)从该带缓冲区的字节输入流读取最多 b.length 个字节的数据放入 字节数组b,并返回读取到的字节个数
intread(byte[] b, int off, int len)从该带缓冲区的字节输入流读取最多 len 个字节的数据放入 字节数组b,并返回读取到的字节个数
voidclose()关闭此带缓冲区的字节输入流并释放与流相关联的任何系统资源
  • 代码演示
package com.wei.java.basic.io;

import java.io.BufferedInputStream;
import java.io.FileInputStream;

/**
 * @author: wei
 * @date 2022/5/7 21:25
 * 说明:
 **/
public class BufferedInputStream_my {
    public static void main(String[] args) {
        String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
        try (
                FileInputStream fis = new FileInputStream(filePath);
                BufferedInputStream bis = new BufferedInputStream(fis);
        ) {
            // .read() 读取一个字节,并返回
            int byteInt = bis.read();
            System.out.println(byteInt +" -> " + (char)byteInt);

            // fis 流已经传入 bis 流,并且已经开始读取 bis 流后,再从 fis 流里读取,是读取不到数据的
            byte[] temp = new byte[3];
            int fisReadByteInt = fis.read(temp); // 这里是读取不到数据的
            System.out.println(fisReadByteInt);

            // .read(bytes),每次只从流中读取2个字节,UTF-8编码,一个汉字占3个字节
            byte[] bytes = new byte[2];
            int len;
            while ((len = bis.read(bytes)) != -1){
                // new String() 强行将一个汉字的 2 个字节转为字符串,会乱码
                System.out.print(new String(bytes));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

BufferedOutputStream 带缓冲区的字节输出流
  • 构造方法
构造器方法说明
BufferedOutputStream(OutputStream out)有参构造器,传入 OutputStream 对象
  • 常用方法
返回类型方法方法说明
voidwrite(int b)将一个字节整型数字,写入该带缓冲区的字节输出流
voidwrite(byte[] b)b.length 个字节从 字节数组b 写入该带缓冲区的字节输出流
voidwrite(byte[] b, int off, int len)字节数组b中,从 偏移量off 开始的 len个字节 数据,写入到该带缓冲区的字节输出流
voidclose()关闭此带缓冲区的字节输出流并释放与流相关联的任何系统资源,只有 close() 后,数据才会真正写到磁盘
  • 代码演示
package com.wei.java.basic.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

/**
 * @author: wei
 * @date 2022/5/7 21:30
 * 说明:
 **/
public class BufferedOutputStream_my {
    public static void main(String[] args) {
        String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
        String outFilePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\out_01.txt";
        try (
                FileInputStream fis = new FileInputStream(filePath);
                BufferedInputStream bis = new BufferedInputStream(fis);

                FileOutputStream fos = new FileOutputStream(outFilePath);

        ) {
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            byte[] bytes = new byte[2];
            int len;
            while ((len = bis.read(bytes)) != -1) {
                bos.write(bytes, 0, len);
            }
            // 只有 执行了 flush(),才会输出到磁盘,close()内调用了 flush()  方法
            bos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

ObjectInputStream 对对象操作的字节输入流、ObjectInputStream 对对象操作的字节输出流
  • 构造方法
  • 常用方法
    用得少,主要用于序列化与反序列化

字符流

FileReader 对文件操作的字符输入流
  • 构造方法
构造器方法说明
FileReader(File file)有参构造,传入 File 对象
FileReader(String fileName)有参构造,传入文件路径(含文件名)
  • 常用方法
返回类型方法方法说明
intread()从该字符输入流中读取 下一个字符,并返回 该字符 对应的 整型数值
intread(char[] cbuf)从该字符输入流读取最多 cbuf.length 个字符的数据放入 字符数组cbuf,并返回读取到的字符个数
intread(char[] cbuf, int offset, int length)从该字符输入流读取最多 length 个字节的数据放入 字符数组cbuf,并返回读取到的字符个数
voidclose()关闭流并释放与之相关联的任何系统资源
  • 代码演示
package com.wei.java.basic.io;

import java.io.FileReader;
import java.io.IOException;

/**
 * @author: wei
 * @date 2022/5/8 10:11
 * 说明:
 **/
public class FileReader_my {
    public static void main(String[] args) throws Exception {
        String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
        try (
                FileReader fr = new FileReader(filePath);
        ) {

            int charInt = fr.read();
            System.out.println((char) charInt);

            char[] bytes = new char[2];
            int len;
            while ((len = fr.read(bytes)) != -1) {
                System.out.print(new String(bytes));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

FileWriter 对文件操作的字符输出流
  • 构造方法
构造器方法说明
FileWriter(File file)有参构造,传入 File 对象,给一个File对象构造一个FileWriter对象。
FileWriter(File file, boolean append)
FileWriter(String fileName)有参构造,传入文件路径(含文件名)
FileWriter(String fileName, boolean append)有参构造,传入文件路径(含文件名),append 设置是否追加写入数据,true-追加,false-覆盖,默认false
  • 常用方法
返回类型方法方法说明
voidwrite(int c)写一个字符
voidwrite(char[] cbuf, int off, int len)字符数组cbuf 中,从 偏移量off 开始的 len个字符 数据,写入到该文件字符输出流
voidwrite(String str, int off, int len)字符串str 中,从 偏移量off 开始的 len个字符 数据,写入到该文件字符输出流
voidflush()刷新流,需要刷新流,数据才会真正写入到文件
voidclose()内部调用刷新流方法,再关闭流,释放资源
  • 代码演示
package com.wei.java.basic.io;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * @author: wei
 * @date 2022/5/8 10:29
 * 说明:
 **/
public class FileWriter_my {
    public static void main(String[] args) throws IOException {
        String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
        String outFilePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\out_01.txt";
        try (
                FileReader fr = new FileReader(filePath);

        ){
            FileWriter fw = new FileWriter(outFilePath);

            // 写入单个字符
            fw.write("w");

            // 循环 读取 -> 写入
            char[] chars = new char[2];
            int len;
            while ((len = fr.read(chars)) != -1){
                fw.write(chars, 0, len);
            }

            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

BufferedReader 带缓冲区的字符输入流
  • 构造方法
构造器方法说明
BufferedReader(Reader in)有参构造,传入 Reader 对象
  • 常用方法
返回类型方法方法说明
intread()从该带缓冲区的字符输入流中读取 下一个字节,并返回 该字节 对应的 整型数值
intread(char[] cbuf)从该带缓冲区的字符输入流读取最多 cbuf.length 个字符的数据放入 字符数组cbuf,并返回读取到的字符个数
intread(char[] cbuf, int offset, int length)从该带缓冲区的字符输入流读取最多 length 个字节的数据放入 字符数组cbuf,并返回读取到的字符个数
StringreadLine()读取一行字符串,并返回该行字符串
voidclose()关闭流并释放与之相关联的任何系统资源
  • 代码演示
package com.wei.java.basic.io;

import java.io.BufferedReader;
import java.io.FileReader;

/**
 * @author: wei
 * @date 2022/5/8 10:42
 * 说明:
 **/
public class BufferedReader_my {
    public static void main(String[] args) throws Exception {
        String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
        FileReader fr = new FileReader(filePath);
        BufferedReader br = new BufferedReader(fr);

        // 读取单个字符
        int charInt = br.read();
        System.out.println((char) charInt);
        // 读取一行字符串
        String line = br.readLine();
        System.out.println(line);

        // 按行,循环读取
        String src;
        while ((src = br.readLine()) != null) {
            System.out.println(src);
        }

        // 只需要关闭缓冲流,缓冲流内部会把它包装的流都关掉
        br.close();
    }
}

BufferedWriter 带缓冲区的字符输出流
  • 构造方法
构造器方法说明
BufferedWriter(Writer out)有参构造,传入 Writer 对象
  • 常用方法
返回类型方法方法说明
voidwrite(int c)写一个字符
voidwrite(char[] cbuf, int off, int len)字符数组cbuf 中,从 偏移量off 开始的 len个字符 数据,写入到该带缓冲区的字符输出流
voidwrite(String str, int off, int len)字符串str 中,从 偏移量off 开始的 len个字符 数据,写入到该带缓冲区的字符输出流
voidnewLine()写入一换行符
voidflush()刷新流,需要刷新流,数据才会真正写入到文件
voidclose()内部调用刷新流方法,再关闭流,释放资源
  • 代码演示
package com.wei.java.basic.io;

import java.io.*;

/**
 * @author: wei
 * @date 2022/5/8 10:42
 * 说明:
 **/
public class BufferedWriter_my {
    public static void main(String[] args) throws Exception {
        String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
        String outFilePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\out_01.txt";
        try (
                // 在 try() 括号里创建的流,方法运行结束,会自动调用 close() 方法,
                // 因为JDK8 及以上版本 编译后代码会在 finally 块里加上 close() 方法
                FileReader fr = new FileReader(filePath);
                BufferedReader bf = new BufferedReader(fr);
                FileWriter fw = new FileWriter(outFilePath);
        ) {

            BufferedWriter bw = new BufferedWriter(fw);

            // 方式1:
            //String line;
            //while ((line = bf.readLine()) != null) {
            //    bw.write(line, 0, line.length());
            //}
            //bw.close();

            // 方式2:
            char[] chars = new char[2];
            int len;
            while ((len = bf.read(chars)) != -1) {
                bw.write(chars, 0, len);
            }
            // 只有关闭流,数据才会输出到磁盘
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

常用流的分类与选择

在这里插入图片描述

小结:

  • 字符流只适用于操作纯文本文件
  • 字节流可以操作任何文件
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值