VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Java教程 >
  • day36-IO流03

4.常用的类02

4.4节点流和处理流

202209111555

4.4.1基本介绍

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

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

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

  • 节点流和处理流的区别和联系:
  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属于字符流,是按照字符来读取数据的

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

  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. 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

  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. 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

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

出处:https://www.cnblogs.com/liyuelian/p/16684898.html


相关教程