小滴课堂-学习笔记:(11)Java进阶核心之Input、Output Stream流

33 篇文章 0 订阅
20 篇文章 0 订阅

logo 愿景:"让编程不再难学,让技术与生活更加有趣"


更多架构课程请访问 xdclass.net

 

目录

第1集 Java核心包 java.io包介绍

第2集 Java输入流InputStream讲解

第3集 Java输出流 OutputStream讲解

第4集 Java IO包之缓冲Buffer输入输出流

第5集 缓冲输入输出流之Java文件拷贝实战

第6集 本章课程作业练习题布置

干货文档


第1集 Java核心包 java.io包介绍

简介: 介绍什么是IO,在开发中的使用场景

  • IO: Input / Ouput 即输入输出

    • 输出流:程序(内存)--->外界设备

    • 输入流:外界设备--->程序(内存)

  • 处理数据类型分类

    • 字符流:处理字符相关,如处理文本数据(如txt文件), Reader/Writer

    • 字节流: 处理字节相关,如声音或者图片等二进制,InputStream/OutputStream

  • 两者区别:

    • 字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节

    • 字节流可以处理几乎所有文件,字符流只能处理字符类型的数据

  • 功能不同,但是具有共性内容,通过不断抽象形成4个抽象类,抽象类下面有很多子类是具体的实现

    • 字符流 Reader/Writer

    • 字节流 InputStream/OutputStream

     

  • IO流相关类体系概览

 

 

第2集 Java输入流InputStream讲解

简介:讲解InputStream相关介绍及其子类

  • InputStream是输入字节流的父类,它是一个抽象类(一般用他的子类)

    int read()  
    讲解:从输入流中读取单个字节,返回0到255范围内的int字节值,字节数据可直接转换为int类型, 如果已经到达流末尾而没有可用的字节,则返回-1
    ​
    int read(byte[] buf) 
    讲解:从输入流中读取一定数量的字节,并将其存储在缓冲区数组buf中, 返回实际读取的字节数,如果已经到达流末尾而没有可用的字节,则返回-1
    ​
    long skip(long n)
    讲解:从输入流中跳过并丢弃 n 个字节的数据。
    ​
    int available()
    讲解:返回这个流中有多少个字节数,可以把buf数组长度定为这个
    ​
    void close() throws IOException
    讲解:关闭输入流并释放与该流关联的系统资源
    

     

  • 常见子类

    • FileInputStream

      • 抽象类InputStream用来具体实现类的创建对象, 文件字节输入流, 对文件数据以字节的形式进行读取操作

      • 常用构造函数

      //传入文件所在地址
      public FileInputStream(String name) throws FileNotFoundException
      ​
      //传入文件对象
      public FileInputStream(File file) throws FileNotFoundException
      • 实战

          public static void main(String[] args) throws IOException {
      ​
              String dir ="C:\\Users\\79466\\Desktop;
      ​
              String name = "a.txt";
      ​
              File file = new File(dir, name);
      ​
      ​
              InputStream inputStream = new FileInputStream(file);
      ​
              testReadByteArr(inputStream);
      ​
          }
      ​
          public static void testRead(InputStream inputStream) throws IOException {
      ​
              //对于汉字等unicode中的字符则不能正常读取,只能以乱码的形式显示
              int read = inputStream.read();
      ​
              System.out.println(read);
      ​
              System.out.println((char) read);
          }
      ​
      ​
          public static void testSkip(InputStream inputStream) throws IOException {
      ​
              long skipSize = inputStream.skip(2);
              System.out.println(skipSize);
              int read = inputStream.read();
      ​
              System.out.println(read);
      ​
              System.out.println((char) read);
          }
      ​
      ​
          public static void testReadByteArr(InputStream inputStream) throws IOException      {
      ​
              //如果 buf 的长度为 0,则不读取任何字节并返回 0; 每次读取的字节数最多等于buf 的长度;
              byte[] buf = new byte[1024];
      ​
              int length;
      ​
              //循环读取文件内容,输入流中将最多buf.length个字节的数据读入一个buf数组中,返回类型是读取到的字节数。
              //如果这个缓冲区没有满的话,则返回真实的字节个数
              //当文件读取到结尾时返回 -1,循环结束。
      ​
              while ((length = inputStream.read(buf)) != -1) {
      ​
                  System.out.print(new String(buf, 0, length));
      ​
                  //中文乱码问题,换成GBK 或者 UTF-8
                  //System.out.println(new String(buf,"UTF-8"));
                  //System.out.println(new String(buf,0, length,"UTF-8"));
                  //System.out.println(new String(buf, 0, length));
      ​
              }
              //最后记得关闭流
              inputStream.close();
          }
      ​
      

       

    • ByteArrayInputStream 字节数组输入流

    • ObjectInputStream 对象输入流

      ....还有很多

 

 

 

第3集 Java输出流 OutputStream讲解

简介:讲解OutputStream相关介绍及其子类

  • OutputStream是输出字节流的父类,它是一个抽象类

    void write(int b)
    讲解:将指定的字节写入输出流
    ​
    ​
    void write(byte[] b)throws IOException
    讲解:将b.length个字节的byte数组写入当前输出流
    ​
    ​
    void flush() throws IOException
    讲解:write是写到缓冲区中,可以认为是内存中,当缓冲区满时系统会自动将缓冲区的内容写入文件,但是一般还有一部分有可能会留在内存这个缓冲区中, 所以需要调用flush空缓冲区数据。
    ​
    ​
    void close() throws IOException
    讲解:关闭输入流并释放与该流关联的系统资源
    

     

  • 常见子类

    • FileOutputStream

      • 抽象类OutputStream用来具体实现类的创建对象, 文件字节输出流, 对文件数据以字节的形式进行输出的操作

      • 构造函数

      //传入输出的文件地址
      public FileOutputStream(String name)
       
      //传入目标输出的文件对象
      public FileOutputStream(File file) 
      ​
      //传入目标输出的文件对象, 是否可以追加内容
      public FileOutputStream(File file, boolean append)
      • 实战

       public static void main(String[] args) throws IOException {
      ​
              String dir = "C:\\Users\\79466\\Desktop;
      ​
              String name = "a.txt";
      ​
              String target = "b.txt";
      ​
              File file = new File(dir, name);
      ​
      ​
              InputStream inputStream = new FileInputStream(file);
      ​
              //会自动创建文件,但是不会创建多级目录下的文件
              OutputStream outputStream = new FileOutputStream("/Users/xdclass/Desktop/test/"+target);
      ​
              // 不覆盖文件,追加数据
              //OutputStream outputStream = new FileOutputStream("/Users/xdclass/Desktop/test/"+target,true);
      ​
              //testOutBuf(inputStream ,outputStream);
              testOut(inputStream,outputStream);
      ​
          }
      ​
      ​
          //单个字节读取,中文会有问题
          public static void testOut(InputStream inputStream, OutputStream outputStream) throws IOException {
      ​
              int value =0 ;
              while ( value !=-1) {
                  value = inputStream.read();
                  outputStream.write(value);
              }
              //最后记得关闭流
              inputStream.close();
              outputStream.close();
          }
      ​
       public static void testOutBuf(InputStream inputStream, OutputStream outputStream) throws IOException {
      ​
              byte[] buf = new byte[1024];
      ​
              int length;
              while ((length = inputStream.read(buf)) != -1) {
      ​
                  outputStream.write(buf,0,length);
              }
              //最后记得关闭流
              inputStream.close();
              outputStream.close();
          }

       

    • ByteArrayOutputStream

    • ObjectOutputStream

 

第4集 Java IO包之缓冲Buffer输入输出流

简介:讲解缓存输入流BufferInputStream,和缓冲输出流BufferOutputStream

  • 什么是缓冲 Buffer 它是内存空间的一部分,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分空间就叫做缓冲区,缓冲区是具有一定大小的,

  • 为啥要用缓冲

    • 缓冲,缓和冲击,例如操作磁盘比内存慢的很多,所以不用缓冲区效率很低

    • 数据传输速度和数据处理的速度存在不平衡,比如你每秒要写100次硬盘,对系统冲击很大,浪费了大量时间在忙着处理开始写和结束写这两个事件,用buffer暂存起来,变成每10秒写一次硬盘,数据可以直接送往缓冲区,高速设备不用再等待低速设备,对系统的冲击就很小,写入效率高了

  • Java IO包里面的两个缓冲类(高级流)

    • BufferInputStream 和 BufferOutputStream

    • 采用包装设计模式(锦上添花的意思)

    • 画图

  • BufferInputStream 缓冲字节输入流

    • BufferedInputStream 通过预先读入一整段原始输入流数据至缓冲区中,而外界对BufferedInputStream的读取操作实际上是在缓冲区上进行,如果读取的数据超过了缓冲区的范围,那么BufferedInputStream负责重新从原始输入流中载入下一截数据填充缓冲区,然后外界继续通过缓冲区进行数据读取。

    • 好处:避免了大量的磁盘IO,原始的InputStream类实现的read是即时读取的,每一次读取都会是一次磁盘IO操作(哪怕只读取了1个字节的数据),如果数据量巨大,这样的磁盘消耗非常可怕。

    • 缓冲区的实现: 读取可以读取缓冲区中的内容,当读取超过缓冲区的内容后再进行一次磁盘IO,载入一段数据填充缓冲,下一次读取一般情况就直接可以从缓冲区读取,减少了磁盘IO。

    • 默认缓冲区大小是8k, int DEFAULT_BUFFER_SIZE = 8192;

    • 常见构造函数

      //对输入流进行包装,里面默认的缓冲区是8k
      public BufferedInputStream(InputStream in);
      ​
      //对输入流进行包装,指定创建具有指定缓冲区大小的
      public BufferedInputStream(InputStream in,int size);

       

  • 常用的两个方法

    /从输入流中读取一个字节
    public int read();
    ​
    //从字节输入流中给定偏移量处开始将各字节读取到指定的 byte 数组中。
    public int read(byte[] buf,int off,int len);
    ​
    //关闭释放资源,关闭的时候这个流即可,InputStream会在里面被关闭
    void close();
    

     

  • BufferOutputStream 缓冲字节输出流

    • 常见构造函数

    //对输出流进行包装,里面默认的缓冲区是8k
    public BufferedOutputStream(OutputStream out);
    ​
    //对输出流进行包装,指定创建具有指定缓冲区大小的
    public BufferedOutputStream(OutputStream out,int size);

     

  • 常用的三个方法

  //向输出流中输出一个字节
  public void write(int b);
​
  //将指定 byte 数组中从偏移量 off 开始的 len 个字节写入缓冲的输出流。
  public void write(byte[] buf,int off,int len);
​
  //刷新此缓冲的输出流,强制使所有缓冲的输出字节被写出到底层输出流中。
  public void flush();
​
  //关闭释放资源,关闭的时候这个流即可,OutputStream会在里面被关闭, JDK7新特性try(在这里声明的会自动关闭){}
  void close();


第5集 缓冲输入输出流之Java文件拷贝实战

简介:使用缓冲输入输出流完成文件拷贝

  • 完成一个文件的拷贝

  
  try {
            FileInputStream fis = new FileInputStream("C:\\Users\\79466\\Desktop\\test\\xdclass.txt");
            BufferedInputStream bis = new BufferedInputStream(fis);
​
            FileOutputStream fos = new FileOutputStream("C:\\Users\\79466\\Desktop\\txet\\copy.txt");
            BufferedOutputStream bos = new BufferedOutputStream(fos);
​
            int size;
            byte[] buf = new byte[1024];
            while ((size = bis.read(buf)) != -1) {
                bos.write(buf, 0, size);
            }
            //刷新此缓冲的输出流,才可以保证数据全部输出完成,close会自动关闭
            //bos.flush();
​
            //关闭的时候只需要关闭最外层的流就行了,源码里面会自动关闭inputstream对象的
            bis.close();
            bos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
  • 注意点

    • BufferedOutputStream在close()时会自动flush

     public void close() throws IOException {
          try (OutputStream ostream = out) {
              flush();
          }
      }
    • BufferedOutputStream在不调用close()的情况下,缓冲区不满,又需要把缓冲区的内容写入到文件或通过网络发送到别的机器时,才需要调用flush.

  • 流的关闭顺序

    • 后开先关, 如果A依赖B,先关闭B

 

 

 

第6集 本章课程作业练习题布置

简介: 根据本章知识点布置课程作业

  • 把某个目录下的全部图片,全部拷贝到另外一个目录

 

第7集 本章课程作业常见问题和答案解析

简介: 讲解课程作业常见问题和答案解析

    public static void main(String[] args) throws IOException {
​
        String dir = "/Users/jack/Desktop";
        File file = new File(dir+"/img1");
        File [] files = file.listFiles();
​
        for (File from : files){
            String fileName = from.getName();
            copy(from.getAbsolutePath(),dir+"/img2/"+fileName);
        }
​
    }
​
    public static void copy(String from,String to) throws IOException {
​
        try {
​
            File targetDir = new File(new File(to).getParent());
            if(!targetDir.exists()){
                targetDir.mkdirs();
            }
​
            FileInputStream fis = new FileInputStream(from);
            BufferedInputStream bis = new BufferedInputStream(fis);
​
            FileOutputStream fos = new FileOutputStream(to);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
​
            int size;
            byte[] buf = new byte[1024];
            while ((size = bis.read(buf)) != -1) {
                bos.write(buf, 0, size);
            }
            //刷新此缓冲的输出流,才可以保证数据全部输出完成
            //bos.flush();
            bis.close();
            bos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
​
    }

干货文档

                                                        关注公众号发送:“CSDN干货文档”  即可领取

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dev666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值