你真的懂IO流吗

2022-08-06 00:00:00 io 你真 流吗

目录

  • 什么是IO流
    • IO流的分类
      • 输入输出流
      • 字节字符流
  • File类
  • IO四大家族
  • 常用类
    • 文件流
      • FileInputStream:文件字节输入流
      • FileOutputStream:文件字节输出流
      • FileReader:文件字符输入流
      • FileWriter:文件字符输出流
      • 代码实现文件的拷贝
    • 缓冲流
      • BufferedInputStream带缓冲的字节输入流
      • BufferedOutputStream带缓冲的字节输出流
      • BufferedReader带缓冲的字符输入流
      • BufferedWriter带缓冲的字符输出流
    • 转换流(字节流—>字符流)
      • InputStreamReader字节输入流–>字符输入流
      • OutputStreamWriter字节输出流–>字符输出流
    • 数据流
      • DataOutputStream(数据输出字节流)
      • DataInputStream(数据输入字节流)
    • 标准输出流
      • PrintStream
      • PrintWriter
    • 对象流
      • ObjectOutputStream对象输出字节流
      • ObjectInputStream对象输入字节流
  • 总结

什么是IO流

在我们的程序运行当中,不可避免的要与数据打交道,我们应该如何获取这些数据?这就用到IO流了
IO:Input/Output,输入/输出流
作用:通过IO流可以完成硬盘文件的读写操作

IO流的分类

《你真的懂IO流吗》

输入输出流

《你真的懂IO流吗》

输入(Input):也就是从外部文件中获取数据(即读取外部数据)
eg:在腾讯视频上看一部电影
《你真的懂IO流吗》
输出(Output):也就是把内存中的文件保存到硬盘上(即把数据写到电脑中)
eg:保存world文档到C盘
《你真的懂IO流吗》

字节字符流

字节流:一看这个名字就知道它是以字节为单位传送数据的,一次传送一个字节byte(即一次传送8个二进制位)
注意:它是一个万能流,什么数据都可以传输,eg:视频、文本、语音、图片(以Stream结尾的类都是字节流)
字符流:字符字符,以字符为单位进行数据的传输,一次传输一个字符
注意:它只能传输普通的文本信息,不能读取非文本信息(以Reader/Writer结尾的类都是字符流)
挺抽象的,举个例子:
假设一个temp文件的内容为
《你真的懂IO流吗》
在Windows系统中,字母占用1个字节,汉字占用两个字节
用字节流的方式读取的话,第一次会读取到97(a对应的字节码),第二次读取到98(b对应的字节码),第三次是99(c),第四次会是206(因为’我’对应的字节码为25105,它是两个字节,所以一次会输出一半,也就是一个字节),so第五次会是210…
《你真的懂IO流吗》
用字符流的方式读取的话,第一次会读取到’a’,第二次会读取到’b’,第三次是’c’,第四次是’我’,第五次是’爱’(一个汉字也是一个字符)
《你真的懂IO流吗》

File类

咱先来说一下这个File类,它也是java.io下的一个类,file是文件的意思,也就是一个文件类,它里面就是包括一下文件的基本方法,文件的基本属性,咱就先来测试一下

先补充一个小知识点:相对路径和绝对路径
相对路径:相对嘛,肯定就是相对于当前文件来说的,例如你在MyEclipse的一个项目里创建了一个temp文件,那你就可以路径名就可以直接写成temp,这就是相对路径
绝对路径,绝对嘛,肯定是在哪里都可以用这个路径,这个路径指的就是在电脑硬盘里真正的路径,eg:D:\java_projects\test2\temp就是绝对路径

File文件其实就是文件和目录路径名的抽象表示形式(原话在JDK帮助文档哈)
话不多说,看代码(当当当,我想着直接把代码拷过来确实看着很费劲,so,I 换成了photo)哈哈
《你真的懂IO流吗》

IO四大家族

《你真的懂IO流吗》

常用类

java为我们提供了很多很多的IO相关的类,下面主要介绍十六种较为常见的类

文件流

java.io.FileInputStream:文件字节输入流
java.io.FileOutputStream:文件字节输出流
java.io.FileReader:文件字符输入流
java.io.FileWriter:文件字符输出流

FileInputStream:文件字节输入流

当我们需要从文件中读取一些信息的时候就会用到这个流,直接上代码!!
《你真的懂IO流吗》
《你真的懂IO流吗》
总结:
FileInputStream是一个万能流,可以读取任意文件的数据,首先要定义一个文件字节输入流对象,把要读取的文件地址传进去,然后调用read()方法来进行字节的读取,read()方法返回的是一个int型的字节码数,当读完数据的时候回返回-1;我们也可以让它一下读取一个bye数组,读取的字节长度是byte[].length个字节,read(byte [])方法返回的是读取了几个字节,读取的字节码存储在byte[]数组中,读完数据压缩会返回-1,读取的时候建议采用循环来读取,最后不要忘记关闭流

FileOutputStream:文件字节输出流

《你真的懂IO流吗》
《你真的懂IO流吗》
总结:
首先创建一个 FileOutputStream字节输出流对象,将写入文件的地址信息传进去,如果文件不存在系统会自动新建,调用write()方法开始写,参数为要写入数据的字节码数,一次只能写一个;也可以一下写一个byte[]数组,调用read(byte[])方法;要写入字符串的时候可以调用getBytes()方法将字符串转化为byte[]数组,输出流最后要记得刷新flush()一下,清空要写入的数据以防止数据丢失,记得还要close()关闭一下。

FileReader:文件字符输入流

《你真的懂IO流吗》
《你真的懂IO流吗》
总结:
FileReader是一个纯文本的输入流,只能进行文本文件的读入,输入时,首先创建一个文件字符输入对象,把要读的文件地址放进去,调用read()方法开始读,它一次读取一个字符,返回的是int型的字符编码,读到最后无数据会返回-1,;也可以一下读取一个char[]数组,读取的长度为char[].length个长度,调用read(char[])开始读,返回的是读取了几个字符,读到最后也是返回-1,可以利用String的一个构造器String(char value[], int offset, int count)来进行char[]与String的转换,最后不要忘记关闭流

FileWriter:文件字符输出流

《你真的懂IO流吗》
《你真的懂IO流吗》
总结:
FileWriter是文件字符输出流,首先创建一个文件字符输出流对象,传入要写入的文件地址,调用write()方法,可以一次一个字符的形式写入,参数为字符码;也调用write(String str, int off, int len)这个方法,传进去一个String字符串;或者一次写一个char[]数组,长度为char[].length个字符,想要换行的时候可以调用write(String str)方法–>即writer(“\n”)以换行,最后记得刷新flush()+关闭close()

代码实现文件的拷贝

《你真的懂IO流吗》
总结:
文件拷贝的思想就是一边读一边写,把读出来的数据放进一个byte[]数组里面,然后再写入到一个文件里面,byte的大小也可以弄个byte[1024*1024](就是一次传输1M),具体可以根据自己的需求来设定

缓冲流

《你真的懂IO流吗》

当一个流的构造器中需要一个流时,被传进来的这个流叫做节点流
外部负责包装的这个流称为包装流,又叫处理流
关闭流的时候只需要关闭包装流就可以了,里面的节点流会自动关闭
Java缓冲流本身并不具有IO流的读取与写入功能,只是在别的流(节点流或其他处理流)上加上缓冲功能提高效率就像是把别的流包装起来一样,缓冲流是一种处理流(包装流)

当对文件或者其他数据源进行频繁的读写操作时,效率比较低,这时如果使用缓冲流就能够更高效的读写信息。
因为缓冲流是先将数据缓存起来,然后当缓存区存满后或者手动刷新时再一次性的读取到程序或写入目的地。

BufferedInputStream带缓冲的字节输入流

有一个temp文件,内容如下:
《你真的懂IO流吗》
《你真的懂IO流吗》
《你真的懂IO流吗》
总结:
BufferedInputStream是一个缓冲字节输入流,其实跟普通的字节输入流的方法差不多,因为它也实现了InputStream接口,有着同样的方法,那为什么会出现这种缓冲流呢,因为普通的输入流它与其他数据源进行频繁的读写操作时,效率较低,使用缓冲流的话就能够更高效的读写信息。
因为缓冲流是先将数据缓存进缓冲区,然后当缓冲区存满后或者手动刷新时会再一次性的读取到程序或写入目的地,这样就极大的解决了它传输数据的效率问题。
并且他相比与普通的输入流多了些方法,eg:mark、reset…等等,mark()方法时将在此输入流中标记当前的位置,reset ()方法的后续调用会在最后标记的位置重新定位此流,以便后续读取重新读取相同的字节
说了这么多,就记着缓冲流比其他效率高就好了

BufferedOutputStream带缓冲的字节输出流

《你真的懂IO流吗》
《你真的懂IO流吗》
总结:
BufferedOutputStream是带缓冲的字节输出流,在我们使用的时候感觉跟普通的输出流差不多,其实他的底层是为我们知道创建了一个缓冲区,我们在想文件中写入数据的时候,数据会被先存放在缓冲区,等缓冲区满的时候,它会将缓冲区的数据一下子传输到输出流中,避免了一个字节一个字节地频繁与底层交互,提高了效率。
通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统

BufferedReader带缓冲的字符输入流

存在一个temp文件,内容为:
《你真的懂IO流吗》
《你真的懂IO流吗》
《你真的懂IO流吗》
总结:
BufferedReader是带缓存的字符缓存输入流,比普通的输入流多了一个readLine()方法,一下读取一行数据,显然比普通的效率要更快,它还有跟BufferedInputStream一样的mark()标记方法和reset()重置方法,这里就不在测试了。

BufferedWriter带缓冲的字符输出流

《你真的懂IO流吗》
《你真的懂IO流吗》
总结:
BufferedWriter是带缓冲区的字符输出流,写入数据的时候更加的方便,它提供了 write(String str)的方法,可以直接写入一个字符串,还有newLine()方法写入一个换行符,当然也可以用write(“\n”),还有write(char cbuf[])方法写入一个char[]数组,底层也是有一个缓冲区来存放将要写入数据,缓冲区的大小也可以在构造器里自己定义,从源码中可以看到,private static int defaultCharBufferSize = 8192;它的么人大小为8192个字符,关闭的时候只需要关闭包装流就可以了,在调用这个方法的时候会把节点流也关闭,刷新flush也是一样,会把缓冲区内的数据给强行输出,缓冲流更高效的完成数据的传输工作

转换流(字节流—>字符流)

它用于字节流转为字符流,eg:在缓冲流中,一个字节输出流想要用Writer字符流,这就可以用到我们的转换流
注意:字符流不能转为字节流(万能字节流才可以转换)

InputStreamReader字节输入流–>字符输入流

《你真的懂IO流吗》
总结:
InputStreamReader实现了字节输入流(InputStream)向字符输入流(Reader)的转变

OutputStreamWriter字节输出流–>字符输出流

《你真的懂IO流吗》
总结:
OutputStreamWriter实现了字节输出流(OutputStream)向字符输出流(Writer)的转变

数据流

DataOutputStream(数据输出字节流)

数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。
《你真的懂IO流吗》
总结:
1.这个流可以将数据连同数据的类型一并写入文件。
2.写出来的这个文件不是普通的文本文档(这个文件使用记事本打不开,会出现乱码,因为写入的数据包含数据类型和数据,需要使用它的兄弟DataInputStream来打开)

DataInputStream(数据输入字节流)

数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用数据输出流写入稍后由数据输入流读取的数据。

《你真的懂IO流吗》
《你真的懂IO流吗》
注意:DataOutputStream写出来的文件只能通过DataInputStream来读,并且读的时候应该提前知道写入的规则读的顺序需要和写的顺序一致,这样才能保证正确取出数据

标准输出流

PrintStream

PrintStream是标准输出流,默认情况下会输出到控制台
我们平常写的System.out.println()其实就是用了PrintStream类,
也就等价于:
PrintStream ps = System.out;
ps.out();
《你真的懂IO流吗》
《你真的懂IO流吗》
PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError ()方法测试的内部标志。另外,为了自动刷新,可以创建一个 PrintStream;这意味着可在写入 byte 数组之后自动调用 flush 方法,可调用其中一个 println ()方法,或写入一个换行符或字节 (’\n’)。

PrintWriter

《你真的懂IO流吗》
《你真的懂IO流吗》
注意:如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作,如果没有,则需要手动flush

对象流

前边学到的数据流只能实现对基本数据类型和字符串类型的读写,并不能读取对象(字符串除外),如果要对某个对象进行读写操作,我们需要用到对象专属的流———对象流(对对象进行读写操作)

ObjectOutputStream对象输出字节流

现在有一个完整的java bean对象Student类,属性有int型的id和String型的name(代码就不补充了)
《你真的懂IO流吗》
总结:
想要传输对象信息的时候,首先创建一个序列化对象(先记住这个名词吧,下次说),通过调用writeObject()方法来写入数据,最后记得强制刷新一下流和关闭。
另外,另外关于序列化与反序列化就放在下次吧,想不到已经写了万字+了哈哈

ObjectInputStream对象输入字节流

《你真的懂IO流吗》
总结:
想要读取对象流信息时,首先要创建一个反序列化对象,通过调用readObject()方法来读取对象信息,该方法返回的是一个Object对象,最后记得关闭流。

总结

关于IO流呢,首先,咱们说了什么是IO流,IO流的两种分类方法,输入流(Input)和输出流(Output)、字节流(Stream)和字符流(Reader/Writer),然后又说到了File类,了解了它的几个常用的方法,接着有又谈了IO的四大家族(Writer、Reader、InputStream、OutputStream),又说了他们的实现类,就是那几种常用的类:文件流、缓冲流、数据流、对象流、标准输出流,挨个说了他们的常用方法与具体使用。
终于写完了,竟然写了一万二多字哈哈,那下次见喽

《你真的懂IO流吗》

    原文作者:钞龙同学
    原文地址: https://blog.csdn.net/m0_47630931/article/details/107234412
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章