Java IO流基础知识详解

Java IO流

1.java IO流概述

1.1 IO流介绍

1.1.1 什么是IO流?
  • 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流
  • 流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作
1.1.2 java中的IO流列表
分类 字节输入流 字节输出流 字符输入流 字符输出流
抽象基类 InputStream OutputStream Reader Writer
访问文件 FileInputStream FileOutputStream FileReader FileWriter
访问数组 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
访问管道 PipedInputStream PipedOutputStream PipedReader PipedWriter
访问字符串 StringReader StringWriter
缓冲流 BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter
转换流 InputStreamReader OutputStreamWriter
对象流 ObjectInputStream ObjectOutputStream
抽象基类 FilterInputStream FilterOutputStream FilterReader FileWriter
打印流 PrintStream
推回输入流 PushbackInputStream PushbackReader
特殊流 DataInputStream DataOutputStream

1.2 IO流分类
1.2.1 按方向分类

(1)输入流(InputStream):从文件或网络 资源中将数据输入到程序中的流

  • FileInputStream:从文件读取数据,是最终数据源;

  • ServletInputStream:从HTTP请求读取数据,是最终数据源;

  • Socket.getInputStream():从TCP连接读取数据,是最终数据源;

(2)输出流(OutStream):从程序中将数据输出到文件或网络的流

13909254-f1cc04b0aacb0e65

1.2.2 按传输单位分类

(1)字符流

  • 字符流以字符为单位,根据码表映射字符,一次读入或写入2个字节,只能用于处理文本,用于读写Unicode编码的字符

(2)字节流

  • 字节流以字节(8bit)为单位,适用于处理所有类型数据,用于读写ASCII字符和二进制数据
1.2.3 按功能分类

(1)节点流:直接与数据源相连,读入或读出

aH

(2)处理流:处理流和节点流一块使用,在节点流的基础上,再套接一层,套接在节点流上的就是处理流

  • 处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接

  • 常用的处理流:

    • 缓冲流BufferedInputStreanBufferedOutputStreamBufferedReaderBufferedWriter :增加缓冲功能,避免频繁读写硬盘。
      转换流InputStreamReaderOutputStreamReader:实现字节流和字符流之间的转换。
      数据流DataInputStreamDataOutputStream :提供将基础数据类型写入到文件中,或者读取出来。

      对象流ObjectInputStreamObjectOutputStream:提供将对象转换成二进制比特流写入到输出流中,也可以将对象从输入流中还原对象数据,构建新对象

    aH


2.常用 java IO流简单使用

  • 以下只给出基础IO流的用法,具体的API使用方法请查看文档

2.1 字符流

2.1.1 FileReader/FileWriter
  • 读取单个字符

    • read()方法返回范围为0x00-0xffff正好为两个字节
    • write(int c)方法的参数值会取低16位构建char类型字符
    public class WriterTest {
         
        public static void main(String[] args) throws IOException {
         
            try (Reader reader = new FileReader("src/test/resources/text.txt");
                 Writer writer = new FileWriter("src/test/resources/out.txt")) {
         
                int len;
                while ((len = reader.read()) != -1) {
         
                    writer.append((char) len);
                }
            } catch (Exception e) {
         
                e.printStackTrace();
        }
        }
    }
    
  • 读取多个字符存放到数组中,并使用read(char[] chars)方法读取或者将该数组构造成CharSequence对象,使用append(CharSqquence c,[int start,int end])方法追加

    int len;
    char[] chars = new char[2048];
    while ((len = reader.read(chars)) != -1) {
         
        writer.append(new String(chars,0,len));
        //reader.read(chars);//或者使用
    }
    
2.1.2 BufferedReader/BufferedWriter
  • BufferedWriter使用缓冲区将一串字符先存到缓冲区,当读或写的数据达到一定量, 再自动往文件里进行读写 ,效率相比FileWrter提高很多

  • 由于设计时使用装饰者模式对原类的一种功能增强,所以使用方法与FileWriter/Reader相同

  • 使用在finally块调用close()关闭流对象之前:

    • 如果是文件读写完的同时缓冲区刚好装满 , 那么缓冲区会把里面的数据朝目标文件自动进行读或写 , 这种时候你直接调用close()方法不会出现问题 ;
    • 但是如果文件在读写完成时 , 缓冲区没有装满 , 就直接调用close()方法 , 这个时候装在缓冲区的数据就不会自动的朝目标文件进行读或写 , 从而造成缓冲区中的这部分数据丢失 , 所以这个是时候就需要在close()之前先调用flush()方法 , 手动使缓冲区数据读写到目标文件
    public class WriterTest {
         
        public static void main(String[] args) throws IOException {
         
            try (Reader reader = new BufferedReader(new FileReader("src/test/resources/text.txt"));
                 Writer writer = new BufferedWriter(new FileWriter("src/test/resources/out.txt",true))) {
         
                int len;
                char[] chars = new char[2048];
                while ((len = reader.read(chars)) != -1) {
         
                    writer.append(new String(chars,0,len));
                    //reader.read(chars);
                }
            } catch (Exception e) {
         
                e.printStackTrace();
            }
        }
    }
    
2.1.3 PiedReader/PiedWriter
  • PiedWriter/Reader是字符管道输出输入流,两者采用生产者消费者模式,当一方工作未完成时,另一方处于阻塞状态

  • PipedWriterPipedReader的作用是可以通过管道进行线程间的通讯。在使用管道通信时,必须将PipedWriterPipedReader配套使用

  • 在使用时可以通过构造方法传入配套字符管道输出输入流来绑定传输方向;也可以通过connect(配套字符管道输出/输入流对象)方法,连接配套字符管道输出/输入流

    • 如果已经连接,第二次连接时会抛出java.io.IOException
    • 可以通过调用public boolean ready()方法判断是否已经连接
    public class WriterTest {
         
        public static void main(String[] args) throws IOException {
         
    
            try(PipedReader reader = new PipedReader();
                PipedWriter writer = new PipedWriter( reader)) {
         
                //reader.connect(writer);
                int len;
                char[] chars = new char[2048];
                writer.write("begin");
                while ((len = reader.read(chars)) != -1) {
         
                    writer.append(new String(chars,0,len));
                    System.out.println((char)reader.read());
                    //reader.read(chars);
                }
            } catch (Exception e) {
         
                e.printStackTrace();
            }
        }
    }
    
2.1.4 InputStreamReader/InputStreamWriter
  • 该类通过传入一个字节流对象构造,是字节流与字符流之间的桥梁,能将字节流输出为字符流,并且能为字节流指定字符集,可输出一个个的字符

  • 构造时可以传入编码方式

    public class WriterTest {
         
        public 
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值