• day36-IO流03


    🚀 优质资源分享 🚀

    学习路线指引(点击解锁)知识定位人群定位
    🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
    💛Python量化交易实战💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

    JavaIO流03

    4.常用的类02

    4.4节点流和处理流

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xTGFk0np-1662957840466)(https://liyuelian.oss-cn-shenzhen.aliyuncs.com/imgs/%E8%8A%82%E7%82%B9%E6%B5%81%E5%92%8C%E5%A4%84%E7%90%86%E6%B5%81%E4%B8%80%E8%A7%88%E5%9B%BE.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yOoeB4PX-1662957840469)(https://liyuelian.oss-cn-shenzhen.aliyuncs.com/imgs/%E8%8A%82%E7%82%B9%E6%B5%81%E5%92%8C%E5%A4%84%E7%90%86%E6%B5%81%E4%B8%80%E8%A7%88%E5%9B%BE2.png)]

    4.4.1基本介绍
    1. 节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter

    数据源就是存放数据的地方,比如文件、数组、字符串、管道等

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fH3tNZ46-1662957840470)(https://liyuelian.oss-cn-shenzhen.aliyuncs.com/imgs/%E8%8A%82%E7%82%B9%E6%B5%81.png)]

    1. 处理流(也叫包装流)是“连接”在已经存在的流(节点流或者处理流)之上,为程序提供更为强大的读写功能,也更加灵活,如BufferedReader、BufferedWriter

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PyahiuuH-1662957840471)(https://liyuelian.oss-cn-shenzhen.aliyuncs.com/imgs/%E5%A4%84%E7%90%86%E6%B5%81.png)]

    • 节点流和处理流的区别和联系:
    1. 节点流是底层流(低级流),直接和数据源相连接。
    2. 处理流(包装流)对节点流进行了包装,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出。
    3. 处理流对节点流进行了包装,使用了修饰器的设计模式,不会直接与数据源相连接。

    image-20220911162032590

    • 处理流特点:

    1.性能的提高:主要以增加缓冲的方式来提高输入输出的效率。

    2.操作的便捷:处理流提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便。

    4.4.2模拟包装流-修饰器模式

    Reader_:

    
    
    |  | package li.io; |
    |  |  |
    |  | /** |
    |  |  * 模拟包装流的修饰器模式 |
    |  |  */ |
    |  | public abstract class Reader\_ {//抽象类 |
    |  | public void readFile() {} |
    |  | public void readString() {} |
    |  | } |
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    FileReader_:

    
    
    |  | package li.io; |
    |  |  |
    |  | public class FileReader\_ extends Reader\_ {//模拟节点流 |
    |  |  |
    |  | public void readFile() { |
    |  |  System.out.println("对文件进行读取..."); |
    |  |  } |
    |  | } |
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    StringReader_:

    
    
    |  | package li.io; |
    |  |  |
    |  | public class StringReader\_ extends Reader\_ {//模拟节点流 |
    |  |  |
    |  | public void readString() { |
    |  |  System.out.println("读取字符串..."); |
    |  |  } |
    |  | } |
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    BufferedReader_:

    
    
    |  | package li.io; |
    |  |  |
    |  | /** |
    |  |  * 模拟处理流(包装流) |
    |  |  */ |
    |  | public class BufferedReader\_ extends Reader\_ { |
    |  | private Reader\_ reader\_;//属性是Reader\_类型 |
    |  |  |
    |  | public BufferedReader\_(Reader\_ reader\_) { |
    |  | this.reader\_ = reader\_; |
    |  |  } |
    |  |  |
    |  | public void readFile(){//封装一层 |
    |  |  reader\_.readFile(); |
    |  |  } |
    |  |  |
    |  | //让方法更加灵活,比如多次读取文件,或者加缓冲byte[]... |
    |  | public void readFile(int num) { |
    |  | for (int i = 0; i < num; i++) { |
    |  |  reader\_.readFile(); |
    |  |  } |
    |  |  } |
    |  |  |
    |  | //又如扩展readString方法,例如批量处理字符串数据... |
    |  | public void readString(int num) { |
    |  | for (int i = 0; i < num; i++) { |
    |  |  reader\_.readString(); |
    |  |  } |
    |  |  } |
    |  | } |
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    Test_:

    
    
    |  | package li.io; |
    |  |  |
    |  | public class Test\_ { |
    |  | public static void main(String[] args) { |
    |  |  |
    |  | BufferedReader\_ bufferedReader\_ = new BufferedReader\_(new FileReader\_()); |
    |  |  bufferedReader\_.readFile(3); |
    |  |  bufferedReader\_.readFile(); |
    |  |  |
    |  | BufferedReader\_ bufferedReader02\_ = new BufferedReader\_(new StringReader\_()); |
    |  |  bufferedReader02\_.readString(2); |
    |  |  } |
    |  | } |
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    image-20220911170145151

    4.4.3字符处理流-BufferedReader&BufferedWriter
    • BufferedReader和BufferedWriter属于字符流,是按照字符来读取数据的
    • 在关闭流时,只需要关闭外层流(即包装流)即可

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-neYuoAmT-1662957840475)(https://liyuelian.oss-cn-shenzhen.aliyuncs.com/imgs/BufferedReader%E7%B1%BB%E5%9B%BE.png)]

    1. BufferedReader构造方法:

    image-20220911190546610
    BufferedReader常用方法:

    
    
    |  | public int read() throws IOException |
    |  | //读取单个字符。 |
    |  | //作为一个整数(其范围从 0 到 65535 (0x00-0xffff))读入的字符,如果已到达流末尾,则返回 -1 |
    |  |  |
    |  | public int read(char[] cbuf) throws IOException |
    |  | //一次读取一个字节数组 |
    |  | //cbuf - 目标缓冲区 |
    |  | //读取的字符数,如果已到达流的末尾,则返回 -1  |
    |  |  |
    |  | public void close() throws IOException |
    |  | //关闭该流并释放与之关联的所有资源。  |
    |  |  |
    |  | public String readLine() throws IOException |
    |  | //读取一个文本行。通过下列字符之一即可认为某行已终止:换行 (’\n’)、回车 (’\r’) 或回车后直接跟着换行。 |
    |  | //包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 nu  |
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19


    2. BufferedWriter构造方法:

    image-20220911191826697
    BufferedWriter常用方法:

    
    
    |  | void write(char ch);//写入单个字符。 |
    |  |  |
    |  | void write(char []cbuf,int off,int len)//写入字符数据的某一部分。 |
    |  |  |
    |  | void write(String s,int off,int len)//写入字符串的某一部分。 |
    |  |  |
    |  | void newLine()//写入一个行分隔符。 |
    |  |  |
    |  | void flush();//刷新该流中的缓冲。将缓冲数据写到目的文件中去。 |
    |  |  |
    |  | void close();//关闭此流,在关闭前会先刷新 |
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    应用案例1:使用BufferedReader读取文本文件,并显示在控制台

    
    
    |  | package li.io.reader\_; |
    |  |  |
    |  | import java.io.BufferedReader; |
    |  | import java.io.FileReader; |
    |  |  |
    |  |  |
    |  | //演示BufferedReader的使用 |
    |  | public class BufferedReader\_ { |
    |  | public static void main(String[] args) throws Exception { |
    |  | String filePath = "d:\\note.txt"; |
    |  | //创建 |
    |  | BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath)); |
    |  |  |
    |  | //读取 |
    |  |  String line; |
    |  | //readLine():按行读取文件,当返回null时,表示文件读取完毕 |
    |  | while((line = bufferedReader.readLine())!=null){ |
    |  |  System.out.println(line); |
    |  |  } |
    |  |  |
    |  | //关闭流:这里只需要关闭BufferedReader,底层会去自动地关闭节点流 |
    |  |  bufferedReader.close(); |
    |  |  } |
    |  | } |
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    image-20220911173953400
    思考:为什么只需要关闭外层流?

    在代码bufferedReader.close();处打上断点,点击force step into,可以看到下图所示:

    在底层调用的其实是:传进去的节点流对象的close()方法

    这里的in就是我们传入的new FileReader(filePath)

    image-20220911174246035

    应用案例2:使用BufferedWriter将“一只可爱的小猫咪”写入到文件中

    
    
    |  | package li.io.writer\_; |
    |  |  |
    |  | import java.io.BufferedWriter; |
    |  | import java.io.FileWriter; |
    |  | import java.io.IOException; |
    |  |  |
    |  | //演示BufferedWriter的使用 |
    |  | public class BufferedWriter\_ { |
    |  | public static void main(String[] args) throws IOException { |
    |  | String filePath = "d:\\ok.txt"; |
    |  |  |
    |  | //创建BufferedWriter对象 |
    |  | BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath)); |
    |  |  |
    |  | //写入 |
    |  |  bufferedWriter.write("一只可爱的小猫咪"); |
    |  |  bufferedWriter.newLine();//插入一个和系统相关的换行 |
    |  |  bufferedWriter.write("两只可爱的小猫咪"); |
    |  |  bufferedWriter.newLine(); |
    |  |  bufferedWriter.write("三只可爱的小猫咪"); |
    |  |  bufferedWriter.newLine(); |
    |  |  |
    |  | //关闭外层流即可,底层自动关闭穿入的内层流 |
    |  |  bufferedWriter.close(); |
    |  |  } |
    |  | } |
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    image-20220911180355401

    案例3:综合使用 BufferedReader & BufferedWriter 完成文件文本拷贝,注意文件编码。

    
    
    |  | package li.io.writer\_; |
    |  |  |
    |  | import java.io.BufferedReader; |
    |  | import java.io.BufferedWriter; |
    |  | import java.io.FileReader; |
    |  | import java.io.FileWriter; |
    |  |  |
    |  | public class BufferedCopy\_ { |
    |  | public static void main(String[] args) throws Exception { |
    |  | //注意:BufferedReader 和 BufferedWriter都是字符流操作 |
    |  | // 不要去操作二进制文件[声音,视频,doc,pdf等],可能造成文件损坏 |
    |  |  |
    |  | String srcFilePath = "d:\\note.txt";//源文件 |
    |  | String destFilePath = "d:\\note2.txt"; |
    |  | String line = null; |
    |  |  |
    |  | //创建BufferedReader&BufferedWriter对象 |
    |  | BufferedReader bufferedReader = new BufferedReader(new FileReader(srcFilePath)); |
    |  | BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(destFilePath)); |
    |  |  |
    |  | //读入和写出 |
    |  | while ((line = bufferedReader.readLine()) != null) {//每读取一行内容就写入 |
    |  |  bufferedWriter.write(line); |
    |  |  bufferedWriter.newLine();//换行 |
    |  |  } |
    |  |  |
    |  |  System.out.println("拷贝完毕~"); |
    |  |  |
    |  | //关闭两个外层流 |
    |  |  bufferedReader.close(); |
    |  |  bufferedWriter.close(); |
    |  |  } |
    |  | } |
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    image-20220911182717923

    4.4.4字节处理流-BufferedInputStream&BufferedOutputStream

    1. BufferedInputStream

    BufferedInputStream是字节流,在创建BufferedInputStream时会创建一个内部缓冲区数组。


    常用方法:

    
    
    |  | int available() |
    |  | //用于返回输入流中可用的未读字节数,而不会由于下一次为此InputStream的方法的调用而阻塞。 |
    |  |  |
    |  | void close() |
    |  | //关闭此输入流并释放与该流关联的所有系统资源。 |
    |  |  |
    |  | void mark(int readlimit) |
    |  | //输入流的当前位置做个标记,readlimit参数是输入流在标记位置失效前允许读取的字节数。 |
    |  |  |
    |  | boolean markSupported() |
    |  | //测试输入流是否支持mark和reset方法。 |
    |  |  |
    |  | int read() |
    |  | //读取一个字节。 |
    |  |  |
    |  | int read(byte[] b, int off, int len) |
    |  | //读取多个字节到字节数组b中,参数off是数组偏移量,参数len是读取数据的长度。 |
    |  |  |
    |  | void reset() |
    |  | //重置流的当前位置到前面标记的位置。 |
    |  |  |
    |  | long skip(long n) |
    |  | //略过流中的数据。若数据不够时,跳过仅有的字节,返回跳过的字节数。 |
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27


    2. BufferedOutputStream

    BufferedOutputStream是字节流,实现缓冲的输出流,可以将多个字节写入底层的输出流中,而不必对每次字节写入调用底层系统

    image-20220911203633605
    image-20220911203655940

    应用案例:

    要求:编程完成图片/音乐的拷贝(要求使用 BufferedInputStream 和 BufferedOutputStream 流)

    
    
    |  | package li.io.outputstream\_; |
    |  |  |
    |  | import java.io.*; |
    |  |  |
    |  | /** |
    |  |  * 演示使用 BufferedInputStream 和 BufferedOutputStream |
    |  |  * 使用它们可以拷贝二进制文件 |
    |  |  * 同时也可以拷贝文本文件 |
    |  |  */ |
    |  |  |
    |  | public class BufferedCopy02 { |
    |  | public static void main(String[] args) { |
    |  | String srcFilePath = "d:\\兰亭序 - 周杰伦.mp3"; |
    |  | String destFilePath = "d:\\ltx-zhou.mp3"; |
    |  |  |
    |  | //创建BufferedInputStream 和 BufferedOutputStream对象 |
    |  | BufferedInputStream bis = null; |
    |  | BufferedOutputStream bos = null; |
    |  |  |
    |  | try { |
    |  |  bis = new BufferedInputStream(new FileInputStream(srcFilePath)); |
    |  |  bos = new BufferedOutputStream(new FileOutputStream(destFilePath)); |
    |  | //循环写入并读取 |
    |  | byte[] buf = new byte[1024]; |
    |  | int readLen = 0; |
    |  | //read(byte[]):当返回-1时就表示文件读取完毕 |
    |  | while ((readLen = bis.read(buf)) != -1) { |
    |  |  bos.write(buf, 0, readLen); |
    |  |  } |
    |  |  } catch (IOException e) { |
    |  |  e.printStackTrace(); |
    |  |  } finally { |
    |  | //关闭外层流 |
    |  | try { |
    |  | if (bos != null) { |
    |  |  bos.close(); |
    |  |  } |
    |  | if (bis != null) { |
    |  |  bis.close(); |
    |  |  } |
    |  |  } catch (IOException e) { |
    |  |  e.printStackTrace(); |
    |  |  } |
    |  |  } |
    |  |  } |
    |  | } |
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    image-20220911212413416

    注意:字节流可以操作二进制文件,同时也可以操作文本文件

  • 相关阅读:
    2022年“新一代”设备管理系统——支持低代码平台
    GB28181安防视频融合汇聚平台EasyCVR如何实现视频画面自定义标签?
    【Git笔记】之Git重命名详解
    C_指针基础4
    基础算法篇——位运算
    【僵尸进程和文件系统调用】
    LeetCode 1345. 跳跃游戏 IV (bfs+哈希表)
    经典模型——NiN&GoogLeNet
    算法强训:第三十二天
    【JVM笔记】Serial回收器:串行回收
  • 原文地址:https://blog.csdn.net/m0_56069948/article/details/126815900