Java常见流的分类及简单讲解

目录

一、梳理总结一 

1.字节流:

2.字符流:

二、梳理总结二

什么是IO流

字符流与字节流的关系

缓冲流BufferedReader/BufferedWriter,BufferedInputStream/BufferedOutputStream


一、梳理总结一 

流在Java中是指计算中流动的缓冲区。

从外部设备流向中央处理器的数据流成为“输入流”,反之成为“输出流”。

字符流和字节流的主要区别:

 1.字节流读取的时候,读到一个字节就返回一个字节;字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在UTF-8码表中是3个字节)时。先去查指定的编码表,将查到的字符返回。

 2.字节流可以处理所有类型数据,如:图片,MP3,AVI视频文件,而字符流只能处理字符数据。只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都用字节流。

1.字节流:

字节输入流类:FileInputStream、BufferedInputStream和DataInputStream

FileInputStream:此类用于从本地文件系统中读取文件内容。

构造方法:

·FileInputStream(File file):打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的File对象file指定。

·FileInputStream(String name):打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的路径名name指定。

常用方法:

·int available():返回下一次对此输入流调用的方法不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。

·void close():关闭此文件输入流并释放与该流关联的所有系统资源。

BufferedInputStream:此类本身带有一个缓冲区,在读取数据时,先放到缓冲区中,可以减少对数据源的访问,提高运行的效率。

构造方法:

·BufferedInputStream(InputStream in):创建一个BufferedInputStream并保存其参数,即输入流in,以便将来使用。

·BufferedInputStream(InputStream in,int size):创建一个具有指定缓冲区大小的BufferedInputStream并保存其参数,即输入流in,以便将来使用。

常用方法:

·int available():返回下一次对此输入流调用的方法不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。

·void close():关闭此输入流并释放与该流关联的所有系统资源。

·int read():从输入流中读取数据的下一个字节。

·int read(byte[] b,int off,int len):从此字节输入流中给定偏移量处开始将各字节读取到指定的byte数组中。

 DataInputStream:该类提供一些基于多字节读取方法,从而可以读取基本数据类型的数据。

构造方法:

·DataInputStream(InputStream in):使用指定的底层InputStream创建一个DataInputStream。

常用方法:

·int read(byte[] b):从包含的输入流中读取一定数量的字节,并将它们存储到缓冲区数组b中。

·int read(byte[] b,int off,int len):从包含的输入流中将最多len个字节读入一个byte数组中。

字节输出流类:FileOutputStream、BufferedOutputStream和DataOutputStream

FileOutputStream:此类用于从本地文件系统的文件中写入数据。

构造方法:

·FileOutputStream(File file):创建一个向指定File对象表示的文件中写入数据的文件输出流。

·FileOutputStream(String name):创建一个向具有指定名称的文件中写入数据的输出文件流。

常用方法:

·void close():关闭此文件输出流并释放与此流有关的所有系统资源。

·FileDescriptor getFD():返回与此流有关的文件描述符。

·void write(byte[] b):将b.length个字节从指定byte数组写入此文件输出流中。

·void write(byte[] b,int off,int len):将指定byte数组中从偏移量off开始的len个字节写入此文件输出流。

·void write(int b):将指定字节写入此文件输出流。

BufferedOutputStream:此类本身带有一个缓冲区,在写入数据时,先放到缓冲区中,实现缓冲的数据流。

构造方法:

·BufferedOutputStream(OutputStream out):创建一个新的缓冲输出流,来将数据写入指定的底层输入流。

·BufferedOutputStream(OutputStream out,int size):创建一个新的缓冲输出流,来将具有指定缓冲区大小的数据写入指定的底层输出流。

常用方法:

·void flush():刷新此缓冲的输出流。

·void write(byte[] b,int off,int len):将指定byte数组中从偏移量off开始的len个字节写入此缓冲的输出流。

·void write(int b):将指定的字节写入此缓冲的输出流。

DataOutputStream(OutputStream out):创建一个新的数据输出流,将数据写入指定基础输出流。

常用方法:

·void flush():清空此数据输出流。

·int size():返回计数器written的当前值,即到目前为止写入此数据输出流的字节数。

·void write(byte[] b,int off,int len):将指定byte数组中从偏移量off开始的len个字节写入基础输出流。

·void write(int b):将指定字节(参数b的八个低位)写入基础输出流。

2.字符流:

FileReader:用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。

构造方法:

·FileReader(File file):在给定从中读取数据的File的情况下创建一个新的FileReader。

·FileReader(String fileName):在给定从中读取数据的文件名的情况下创建一个新的FileReader。

BufferedReader类是Reader类的子类,为Reader对象添加字符缓冲器,为数据输入分配内存存储空间,存取数据更为有效。

构造方法:

·BufferedReader(Reader in):创建一个使用默认大小输入缓冲区的缓冲字符输入流。

·BufferedReader(Reader in,int sz):创建一个使用指定大小输入缓冲区的缓冲字符输入流。

操作方法:

·void close():关闭该流并释放与之关联的所有资源。

·void mark(int readAheadLimit):标记流中的当前为止。

·boolean markSupported();判断此流是否支持mark()操作。

·int read():读取单个字符。

·int read(char[] cbuf,int off,int len):将字符读入数组的某一部分。

·String readLine():读取一个文本行。

·boolean ready():判断此流是否已准备好被读取。

·void reset():将流重置到最新的标记。

·long skip(long n):跳过字符。

FileWriter:用来写入字符文件的便捷类,可用于写入字符流。

构造方法:

·FileWriter(File file):根据给定的File对象构造一个FileWriter对象。

·FileWriter(String filename):根据给定的文件名构造一个FileWriter对象。

BufferedWriter:将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。


Java输入/输出流体系中常用的流分类(表内容来自java疯狂讲义)

注:下表中带下划线的是抽象类,不能创建对象。粗体部分是节点流,其他就是常用的处理流。

流分类使用分类字节输入流字节输出流字符输入流字符输出流
抽象基类InputStream

OutputStream

ReaderWriter
节点流访问文件FileInputStreamFileOutStreamFileReaderFileWriter
访问数值ByteArrayInputStreamByteArrayOutStreamCharArrayReaderCharArrayWriter
访问管道PipedInputStreamPipedOutStreamPipedReaderPipedWriter
访问字符串StringReaderStringWriter
处理流缓冲流BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter
转换流InputStreamReaderOutputStreamWriter
对象流ObjectInputStreamObjectOutputStream
抽象基类(过滤)FilterInputStreamFilterOutputStreamFilterReaderFilterWriter
打印流PrintStreamPrintWriter
推回输入流PushbackInputStreamPushbackReader
特殊流DataInputStreamDataOutputStream

———————————————————————————————————————————————————————

总结:

1.Java IO是采用的是装饰模式,即采用处理流来包装节点流的方式,来达到代码通用性。

2.处理流和节点流的区分方法,节点流在新建时需要一个数据源(文件、网络)作为参数,而处理流需要一个节点流作为参数。

3.处理流的作用就是提高代码通用性,编写代码的便捷性,提高性能。

4.节点流都是对应抽象基类的实现类,它们都实现了抽象基类的基础读写方法。其中read()方法如果返回-1,代表已经读到数据源末尾。

参考链接:https://www.cnblogs.com/lca1826/p/6427177.html

参考链接:https://www.cnblogs.com/moonpool/p/5488463.html

二、梳理总结二

什么是IO流

首先我们要明白什么是流?流是计算机用来传输文件、保存文件的一种方式。我们在开发中会经常用到IO流,如:文件的上传和下载,文件的复制等。根据流的方向,分为输入流和输出流。通常二者搭配使用完成文件上传和下载。输入流就是你要让计算机知道他要操作的是哪个文件,什么文件,要读取到这个文件,这个从外到内的过程就是输入流(InputStream),如文件下载;那么,输出流就刚好相反,它是计算机已经有了这个文件,但开发者希望把这个文件保存到另外一个地方,这种从内到外的过程就是输出流(OutputStream)如文件上传。根据流的分类,输入流又包括字符输入流(FileReader)和字节输入流(InputStream),输出流包括字符输出流(FileWriter)和字节输出流(OutputStream)。虽然也还有其他的输入输出流,但最常用的还是这几种。

如果你觉得IO流只有这些东西那你就大错特错了除了常见的这四种流的表现形式,还用一种很常用的流——缓冲流。但在介绍缓冲流之前,我们要先明白字符流和字节流的关系才能够更好的理解缓冲流

字符流与字节流的关系

说起字符流与字节流的关系,可能有的小伙伴就说了,我前面已经说过了:字符流就是按字符读取文件的形式,一般作用于文本类型的文件;而字节流就是按字节读取文件的形式,一般用来操作视频或图片等文件。但如果仅仅知道这些那就太简单了,为什么字符流通常操作String类、文本文件呢?为什么不能操作字符流操作视频和图片呢?那字节流可以操作文本类型的文件吗?为什么呢?

       其实,这是因为字符流每次按char读取文件,读取文本类型当然没有问题,但视频和图片都属于字节码文件,如果用字符流来输入或输出文件,就会造成乱码。想看效果的同学可以试一下,这就相当于我们把这个图片或视频文件直接以记事本的方式打开了,乱码是必然的。那字节流可以操作文本文件吗?答案是肯定的,为什么呢?我们都知道,计算机存储文件都是以二进制、十进制、十六进制等字节的方式存储的,包括文本文件,所以用字节流操作文本文件是没有问题的。说到这里,很多小伙伴就已经明白两者的关系了,没错,字节流包含字符流,为什么,因为字符流的底层实现也是字节流,它只不过是对字节流的封装罢了。但我们都知道,字符流是以char为单位读取文件的,这会大大影响我们程序的效率,那么怎么解决呢?没错,就是缓冲流。

缓冲流BufferedReader/BufferedWriter,BufferedInputStream/BufferedOutputStream

 我们都知道,StringBuffer的效率远比String的效率高很多,流也一样,缓冲流就是把char类型封装成为了StringBuffer类型。下面我们看一下它的用法,其实都一样。

这里就单举BufferedReader的用法,其他三种与它的方式一样,就不一一列举了。但值得注意的是:

没有经过Buffered处理的IO, 意味着每一次读和写的请求都会由OS底层直接处理,这会导致非常低效的问题。

经过Buffered处理过的输入流将会从一个buffer内存区域读取数据,本地API只会在buffer空了之后才会被调用(可能一次调用会填充很多数据进buffer)。

经过Buffered处理过的输出流将会把数据写入到buffer中,本地API只会在buffer满了之后才会被调用。

BufferedReader/BufferedWriter可以将字符流(Reader)包装成缓冲流,这是最常见用的做法。

另外,BufferedReader提供一个readLine()可以方便地读取一行,而FileInputStream和FileReader只能读取一个字节或者一个字符,

因此BufferedReader也被称为行读取器

以上笔者只是讲解了笔者认为IO流中最常用的几种表现形式。希望能给各位小伙伴提供有效的帮助。不足之处,欢迎补充。

  • 28
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来详细讲解一下Java IO的知识点。 Java IO(Input/Output)Java用于处理输入输出的机制。它提供了一种标准的方法来处理与文件、网络连接、管道等相关的操作。 Java IO被分为两类:字节和字符。 - 字节:以字节为单位进行读写操作,适用于二进制文件或以字节为基础的文本文件的读写操作。字节主要包括InputStream和OutputStream两个类。 - 字符:以字符为单位进行读写操作,适用于以字符为基础的文本文件的读写操作。字符主要包括Reader和Writer两个类。 Java IO的常用类有: 1. FileInputStream 和 FileOutputStream FileInputStream 和 FileOutputStream 是用于读写文件的字节。FileInputStream 可以打开一个文件,读取其中的内容;FileOutputStream 可以打开一个文件,将内容写入文件中。示例代码如下: ```java try (FileInputStream fis = new FileInputStream("input.txt"); FileOutputStream fos = new FileOutputStream("output.txt")) { byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) != -1) { fos.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } ``` 2. FileReader 和 FileWriter FileReader 和 FileWriter 是用于读写文件的字符。FileReader 可以打开一个文件,读取其中的内容;FileWriter 可以打开一个文件,将内容写入文件中。示例代码如下: ```java try (FileReader fr = new FileReader("input.txt"); FileWriter fw = new FileWriter("output.txt")) { char[] buffer = new char[1024]; int len; while ((len = fr.read(buffer)) != -1) { fw.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } ``` 3. ByteArrayInputStream 和 ByteArrayOutputStream ByteArrayInputStream 和 ByteArrayOutputStream 是用于读写内存中的字节。ByteArrayInputStream 可以从一个字节数组中读取内容;ByteArrayOutputStream 可以将内容写入一个字节数组中。示例代码如下: ```java byte[] data = "Hello, world!".getBytes(); try (ByteArrayInputStream bais = new ByteArrayInputStream(data); ByteArrayOutputStream baos = new ByteArrayOutputStream()) { byte[] buffer = new byte[1024]; int len; while ((len = bais.read(buffer)) != -1) { baos.write(buffer, 0, len); } byte[] result = baos.toByteArray(); System.out.println(new String(result)); } catch (IOException e) { e.printStackTrace(); } ``` 4. CharArrayReader 和 CharArrayWriter CharArrayReader 和 CharArrayWriter 是用于读写内存中的字符。CharArrayReader 可以从一个字符数组中读取内容;CharArrayWriter 可以将内容写入一个字符数组中。示例代码如下: ```java char[] data = "Hello, world!".toCharArray(); try (CharArrayReader car = new CharArrayReader(data); CharArrayWriter caw = new CharArrayWriter()) { char[] buffer = new char[1024]; int len; while ((len = car.read(buffer)) != -1) { caw.write(buffer, 0, len); } char[] result = caw.toCharArray(); System.out.println(new String(result)); } catch (IOException e) { e.printStackTrace(); } ``` 5. BufferedReader 和 BufferedWriter BufferedReader 和 BufferedWriter 是用于带缓存的读写字符。示例代码如下: ```java try (BufferedReader br = new BufferedReader(new FileReader("input.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) { String line; while ((line = br.readLine()) != null) { bw.write(line); bw.newLine(); } } catch (IOException e) { e.printStackTrace(); } ``` 6. DataInputStream 和 DataOutputStream DataInputStream 和 DataOutputStream 是用于读写基本数据类型和字符串。示例代码如下: ```java try (DataInputStream dis = new DataInputStream(new FileInputStream("data.bin")); DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.bin"))) { dos.writeInt(123); dos.writeUTF("Hello, world!"); int num = dis.readInt(); String str = dis.readUTF(); System.out.println(num + ", " + str); } catch (IOException e) { e.printStackTrace(); } ``` 7. ObjectInputStream 和 ObjectOutputStream ObjectInputStream 和 ObjectOutputStream 是用于读写Java对象。示例代码如下: ```java class Person implements Serializable { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } } try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.bin")); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.bin"))) { Person p1 = new Person("Alice", 18); oos.writeObject(p1); Person p2 = (Person) ois.readObject(); System.out.println(p2); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } ``` Java IO在处理文件、网络连接、管道等方面具有广泛的应用,是Java编程不可或缺的一部分。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值