6

day36-IO流03 - 一刀一个小西瓜

 2 years ago
source link: https://www.cnblogs.com/liyuelian/p/16684898.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

JavaIO流03

4.常用的类02

4.4节点流和处理流

202209111555
%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

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

%E8%8A%82%E7%82%B9%E6%B5%81.png
  1. 处理流(也叫包装流)是“连接”在已经存在的流(节点流或者处理流)之上,为程序提供更为强大的读写功能,也更加灵活,如BufferedReader、BufferedWriter
%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() {}}

FileReader_:

package li.io; public class FileReader_ extends Reader_ {//模拟节点流 public void readFile() { System.out.println("对文件进行读取..."); }}

StringReader_:

package li.io; public class StringReader_ extends Reader_ {//模拟节点流 public void readString() { System.out.println("读取字符串..."); }}

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(); } }}

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); }}
image-20220911170145151

4.4.3字符处理流-BufferedReader&BufferedWriter

  • BufferedReader和BufferedWriter属于字符流,是按照字符来读取数据的

  • 在关闭流时,只需要关闭外层流(即包装流)即可

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
BufferedWriter.png
  1. 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:使用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(); }}
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(); }}
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(); }}
image-20220911182717923

4.4.4字节处理流-BufferedInputStream&BufferedOutputStream

BufferedInputStream.png
  1. BufferedInputStream

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

image-20220911203907806.png

常用方法:

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)//略过流中的数据。若数据不够时,跳过仅有的字节,返回跳过的字节数。
BufferedOutputStream.png
  1. 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(); } } }}

image-20220911212413416

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK