• Java IO流的“四大家族”


    1. IO流的概述

    理论部分

    简单概括就是文件的输入与输出。

    磁盘中文件的东西放到内存中的这个过程称为输入(Input)或称读(read),由于这个输入的过程会有数据的流动,就有了输入流(InputStream)这个概念

    内存中的文件的东西放到磁盘中去的这个过程称为输出(Output)或称写(Write),输出过程的数据流动称为输出流(OutputStream)

    (不难看出不管是输入流还是输出流,都是以内存为参照物的)

    下面画图描述:

    29e389c326754536b4410eebb0a23099.jpeg

     IO这样看的话就不难理解了,I:Input       O:Output

     IO流的分类

     1)按流的方向:内存为参照物分为:

    输入流(InputStream):往内存中去

    输出流(OutputStream):往内存中出来

    2)读取数据的方式不同:

    字节流:通过一个一个字节对数据进行读取或写入(可以说可用性很强)可用于文本文件,图片,声音文件,视频等......

    字符流:一个一个字符对数据进行读取或写入,一般用来读取纯文本文件(word文本不能称为纯文本,不可以对其进行读取与写入)

    IO流的“四大家族”

    字节流:java.io.InputStream (读操作使用流)

                   java.io.OutStream(写操作使用流)

    字符流:java.io.Reader(读取器)

                   java.io,Writer  (写入器)

    为什么这样称呢?因为待会需要掌握的就是他们的子类,并且他们也有一些共同点:

    • 这四个类都是抽象类(抽象类不能实例化)
    • 这四个类都实现了java.io.Closeable接口——那么他们就都有close()这个方法,可以用来关闭流
    • 输出流中(OutStream和Writer)都实现了Flushable这个接口——那么就都有flush()这个方法,用来刷新该流的缓存,避免丢失数据(Reader和InputStream没有实现这个接口)

    注意:在Java中只要”类名“以Stream结尾的都是字节流,以”Reader/Writer"结尾的都是字符流

    需要掌握的流(16个)

    文件专属:                                                                     数据流专属:          

    FileInputStream                                                              DateInputStream

    FileOutputStream                                                           DateOutputStream

    FileReader                                                                      标准输出流:       

    FileWriter                                                                         PrintWriter

    缓冲专属:                                                                         PrintStream

    BufferedReader                                                               转换流(将字节流转换成字符流):

    BufferedWriter                                                                 InputStreamReader

    BufferedInputStream                                                       OutputStreamWriter

    BufferedOutputStream 

                            对象专属流:ObjectInputStream        ObjectOutputStream  

    (这里说说文件专属那四个流,其他的用起来都差不多)

    FileInputStream

    需要知道的方法:

    构造方法:

    FileInputStream(File file)throws FileNotFoundException

    FileInputStream(String name)throws FileNotFoundException  通过打开一个实际文件的连接来创建一个FileInputStream,这个name就是指那个文件的路径

    方法:

    int read()  从此输入流中读取一个数据字节(一次一个字节,内存与磁盘交互太频繁了,浪费资源,这个一般不用

    int read(byte[] b)  从此输入流中将最多b.length个字节的数据都读入到一个byte数组中(这个常用)(看源声明可以知道,这个返回值是从流中读到的字节个数,没读到会返回-1)

    void close()

    int available()  返回还没有读取到的字节数

    long skig(long n)  从输入流中跳过并丢弃n个字节的数据

    实操:

    a6c1eb25cf7947a7a3573a217e533945.png

     

    avaliable函数能怎么用呢,起初是没有读取数据的,所以流对象.avaliable()就是文件中的数据字节长度,那我们之间new byte[对象名.avaliable]之间读数据一次不就行了吗。

    注意:由于byte数组不能太大,所以使用时得注意,一俩mb的文档或图片啥的还是可以的。

    关闭文件也可以用try with resources,把定义文件流对象写在try()这个括号里,运行完try会自动关闭(资源是一定要关的,防止丢失)

    FileOutputStream

    需要知道的方法:

    构造方法:

    FileOutputStream(File file)throws FileNotFoundException

    FileOutputStream(File file,boolean append)

    FileOutputStream(String name)throws FileNotFoundException  清空文件再进行写操作

    FileOutputStream(String name,boolean append)  表示是否在原文件后追加内容

    方法:

    void close()

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

    void write(byte[] b)  将b.length个字节从byte数组里面读入到文件中

    void write(byte[] b,int off,int len)  将从off位置开始的len个字节写入文件输出流

    实操:

    3d4fe2fb7d02422cbab7e5e6065019a8.png

     学会了FileInputStream 和 FileOutputStream 俩流后(这俩可是万能流),那我们是不是可以试着拷贝一个文件啊?

    实操(将xpp.txt中的内容,拷贝到xpp2.txt里):

    840a927cf6ee4a248b425f8078f06029.png

     那肯定就有人问能不能拼接图片呢?我试了下,就单纯这样直接往一图片后写入一张图片,是拼不了的,应该是要将拷贝图片的那个图片进行压缩,那样就可以使得俩图片拼接了。但单纯拷贝图片这还是挺快挺方便的。

     FileReader

    需要知道的方法:

    构造方法:

    FileReader(File file)

    FileReader(String fileName)

    方法:

    void close()

    int read()  读取单个字符

    int read(char[] cbuf)  将字符读入数组

    long skig(long n)  跳过字符

    实操:

    5adbe3e4a7c14b86ae90b207a402e030.png

     FileWriter

    需要知道的方法:

    构造方法:

    FileWriter(File file)

    FileWriter(File file,boolean append)

    FileWriter(String fileName)

    FileWriter(String fileName,boolean append)

    方法:

    close()

    flush()

    void write(char[] cbuf)

    void write(int c)  //写入单个字符

    void write(String str)
    void write(String str,int off,int len) //输入字符串的某一部分

    (有没有发现这“四大家族”的方法差不多,其实其他的也差不多,读数据的和写数据分类掌握会蛮轻松的)

    实操:

    f40cae55c45d429299c5de02d1176687.png

    有没有发现这个流提供的方法很适合写入东西进文本 

    (运行几次它就写入几次,想无限次复杂粘贴一个东西,暂时想不到比这快的)

    使用学习的这俩个流进行拷贝练习:

    e7baeb4b8fc949529f0f106dc8d1132e.png

     注意:

    1. 流进行操作完后一定要关闭,练习时候可以学会在finally关闭,也可以用try with resources进行操作,在try()括号里进行流的创建

    2. 记事本可以编辑的文本都是普通文本,所以.java文本也是可以进行拷贝的(当有相同的代码不愿写想进行拷贝时候,就可以用了,当然复制粘贴还是yyds)

    3. 当你想写入的文件名不存在的时候,会自动创建一个与你写的文本名一致以及类型一致的文本

    如果嫌创建byte数组和char数组进行操作不方便,可以去看看BufferedReader和BufferedWriter流这俩虽然没前面操作运行起来那么快,但是BufferedReader流里面有个readline()可以读取一行的方法很方便,下面写一下,其他流都有共同点的,掌握起来很方便。

    1. package com.io;
    2. import java.io. *;
    3. public class BufferedReaderText {
    4. public static void main(String[] args) throws Exception{
    5. //这里创建一个文件字符输入流,注意该流是Reader的子类
    6. FileReader in1 = new FileReader("D:\\Java\\eclipse\\xpx.java");
    7. //构建一个缓冲字符输入流 它的构造方法:BufferedReader(Reader in)
    8. BufferedReader bin = new BufferedReader(in1);
    9. //String s = bin.readLine();//读一行
    10. //System.out.println(s);//读取行的这个方法没有读取文本里的换行符
    11. String s = null;
    12. while((s = bin.readLine())!=null)
    13. System.out.println(s);
    14. bin.close();
    15. }
    16. }

    (这里异常比较懒没进行处理,大家写代码别学我)(看完是不是觉得这样写比上面简单多了)

    学无止境嘛~大家可以去了解了解,这里提了“四大家族”,其他所需要掌握的操作其实也差不多。

    acb71fad1ead4d2f92204b1668d702db.gif

     

     

  • 相关阅读:
    Python办公自动化Excel
    使用python玩转二维码!速学速用!⛵
    Spring Boot中的JDK 线程池以及Tomcat线程池使用与配置
    【面试刷题】——Qt事件处理器级别的划分
    Linux下使用Nginx搭建Rtmp流媒体服务器,实现视频直播功能
    【Stable Diffusion】入门-04:不同模型分类+代表作品+常用下载网站+使用技巧
    跟我学c++初级篇——汇编语言的使用
    计算字符在字符串中出现的次数
    离子液体1-乙基-3-甲基咪唑六氟磷酸盐([EMIm][PF6])修饰纳米Fe3O4四氧化三铁(规格)
    react-starter脚手架搭建过程
  • 原文地址:https://blog.csdn.net/qq_63691275/article/details/127013682