Java IO流

IO流

Java IO流是实现输入/输出的基础。
Java把不同的输入/输出源(键盘,文件,网络连接等)抽象为"流",Stream。
通过流的方式使用相同的方式来访问不同的输入/输出源。
stream是从起源(source)到接收(sink)的有序数据。
传统流类型都在 java.io 包中。

流的分类

输入输出流

按照流的流向分为输入流和输出流。是以内存的角度来划分。
输入流: 只能读取数据,不能写入。由InputStream 和 Reader作为基类
输出流: 只能写入数据,不能读取。由OutputStream 和 Writer 作为基类

字节流和字符流

字节流: 操作数据单元为8位字节,由 InputStream 和 OutputStream作为基类
字符流:操作数据单元为16位字符,由 Reader 和 Writer 作为基类

节点流和处理流

按角色分为节点流和处理流。
从一个特定的IO设备(磁盘,或网络)读写数据的流,称为节点流,节点流也被称为低级流(Low Level Stream)。
处理流是对节点流的封装。称为高级流,包装流。
使用装饰器设计模式。

InputStream和Reader

InputStream和Reader都是输入流的抽象基类。
都实现了下面方法

  • read(): 可以读取单个字符或字节,
  • read(byte[] b): 读取 b.length 个字节
  • read(byte[] b, int off, int len): 读取 len 个字节,从 off 位置开始读
  • mark(): 记录指针当前位置记录一个标记
  • markSupported(): 是否支持 mark操作
  • reset():将指针重新定位到上一次记录mark的位置
  • skip(): 指针向前移动 n个字节/字符

FileInputStream 和 FileReader是两个读取文件的输入流。是 InputStream和 Reader的子类。

        FileInputStream fis = new FileInputStream("ReadMe.txt");
        byte[] fbuff = new byte[1024];
        int hasRead = 0;
        while ((hasRead = fis.read(fbuff)) > 0){
            System.out.println(new String(fbuff, 0, hasRead));
        }
        fis.close();
        

程序里打开的 IO资源不属于内存里的资源, 垃圾回收机制无法回收该资源, 所以要显式的关闭IO资源,调用 fis.close()。
InputStream 和 Reader都实现了AutoCloseable 接口, 因此可以通过自动关闭资源的 try 语句来关闭IO流。

public abstract class InputStream implements Closeable {
}

public interface Closeable extends AutoCloseable {
}

OutputStream 和 Writer

OutputStream 和 Writer都是输出流的抽象基类。
都提供了下面方法:

  • write(int c): 指定字符/字节输出
  • write(byte[] buf): 数组输出
  • write(byte[] buf, int off, int len): 将数组中 off 开始, 长度为len 输出
    Writer还包括了支持 String 参数的 writer() 方法。
    FileOutputStream 和 FileWriter 用来文件输出。
        try (FileInputStream fis1 = new FileInputStream("ReadMe.txt");
             FileOutputStream fos = new FileOutputStream("newFIle.txt")){
            
            byte[] fbuff = new byte[32];
            int hasRead = 0;
            while ((hasRead = fis1.read(fbuff)) > 0){
                fos.write(fbuff, 0, hasRead);
            }

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

关闭输出流除了保证资源被回收之外,还可以将输出缓冲区的数据flush到物理节点中。在执行close()之前,自动执行输出流的flush()。
如果是字符串内容,可以直接使用Writer();

        try (FileWriter fileWriter = new FileWriter("t.txt")){

            fileWriter.write("a\r\n");
            fileWriter.write("c test\r\n");
        }
        catch (IOException e){
            e.printStackTrace();
        }

处理流用法

使用处理流包装节点流,对外提供更加方便的输入/输出。
节点流的构造器是以物理IO节点为参数的。
处理流的构造器不是物理IO节点,而是已经存在的流。
下面例子 PrintStream 就是处理流,输出更加方便。

        try(FileOutputStream fos = new FileOutputStream("abc.txt");
            PrintStream ps = new PrintStream(fos)){

            ps.println("test字符串");
            ps.println(new FileTest());
        }
        catch (IOException e){
            e.printStackTrace();
        }

关闭资源时,只需要关闭最上层处理流即可, 关闭处理流时,自动关闭该处理流包装的节点流。

IO流

JAVA IO流体系提供了近40个类。
在这里插入图片描述

转换流

IO体现提供了两个转换流, 将字节流转换为字符流。
InputStreamReader 将字节输入流转为字符输入流
OutputStreamWriter 将字节输出流转为字符输出流

        try (InputStreamReader reader = new InputStreamReader(System.in);
             BufferedReader bufferedReader = new BufferedReader(reader)
        ){
            String line = null;
            while ((line = bufferedReader.readLine()) != null){
                if(line.equals("exit")){
                    System.exit(1);
                }
                System.out.println(line);
            }
        }
        catch (IOException e){
            e.printStackTrace();
        }

System.in 代表标准输入,即键盘输入,这个输入流是 InputStream 类的实例, 使用 InputStreamReader 转为字符输入流。
将 Reader 包装为 BufferedReader, 使用它的 readLine() 方法一次读一行。

推回输入流

PushbackInputStream, PushbackReader 这两个是推回输入流。
提供了 unread () 方法。
这两个输入流都带一个推回缓冲区, 将指定数组内容推回到该缓冲区。
调用 read()时, 先从推回缓冲区读取, 未装满时,再从原缓冲区读取。
需要指定推回缓冲区的大小, 默认为1。

下面例子找到 test 字符串, 输出之前的内容

        try (PushbackReader pushbackReader = new PushbackReader(new FileReader("abc.txt"), 32)){
            char[] buf = new char[32];
            String lastConntent = "";
            int hasRead = 0;
            while ((hasRead = pushbackReader.read(buf)) > 0){
                String content = new String(buf, 0, hasRead);
                int lastIndex = (lastConntent + content).indexOf("test");

                if(lastIndex > 0){
                    pushbackReader.unread((lastConntent + content).toCharArray());
                    if(lastIndex > 32){
                        buf = new char[lastIndex];
                    }
                    pushbackReader.read(buf, 0, lastIndex);
                    System.out.println(new String(buf, 0, lastIndex));
                    System.exit(0);
                }
                else {
                    System.out.println(lastConntent);
                    lastConntent = content;
                }
            }
        }
        catch (IOException e){
            e.printStackTrace();
        }

地址:https://blog.csdn.net/yonggang7/article/details/86776449

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值