IO流解析
1. 概述
-
Java程序中,数据的输入、输出操作以“流(stream)” 的
方式进行 -
I/O是Input/Output的缩写。I/O技术用于处理设备之间的数据传输。如读、写文件、网络通讯等
-
流的分类
(1) 按操作数据单位:字节流(8 bit)、字符流(16 bit)
(2) 按数据流的流向:输入流、输出流
(3) 按流的角色:节点流(直接操作数据)、处理流(操纵节点流)
抽象基类 | 字节流 | 字符流 |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
- 无论流的形式如何,操作流的流程都是如下4步(括号内是比喻)
(1) 创建File对象 (指明管道要连接到哪儿)
(2) 实例化 "流"对象并将File对象作为参数传入"流"的构造器(连接相应的管道)
(3) 通过"流"对象调用方法 (打开管道开关)
(4) 关闭资源 (关闭管道开关)
2. 字符流( FileReader、FileWriter )
3. 字节流(FileInputStream、FileOutputStream)
FileInputStream、FileOutputStream
4. 处理流—缓冲流
- 缓冲流会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区
- 缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:
BufferedInputStream 和 BufferedOutputStream
BufferedReader 和 BufferedWriter - 当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲区。当使用BufferedInputStream读取字节文件时,BufferedInputStream会一次性从文件中读取8192个(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中读取下一个8192个字节数组。
- 向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满,BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法flush()可以强制将缓冲区的内容全部写入输出流
- 关闭最外层流时也会相应关闭内层节点流,所以一般只用关闭最外层的"流"即可
- flush()方法会强制将缓冲区的内容全部写入输出流
- 调用close()方法后不但会关闭流,还会在关闭流之前刷新缓冲区,关闭后不能再写出
//通过缓冲流作用于字节流对视频进行复制
通过对比,发现缓冲流较字节流速度提升了2.5倍左右
public void test() throws IOException
{
long start=System.currentTimeMillis();
File Srcfile = new File("C:\\Users\\mwz\\Desktop\\20200311_DSP.mp4");
File destFile = new File("C:\\Users\\mwz\\Desktop\\copy.mp4");
FileInputStream fis = new FileInputStream(Srcfile);
FileOutputStream fos = new FileOutputStream(destFile);
BufferedInputStream bis=new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] buf=new byte[1024];
int len;
while((len=bis.read(buf))!=-1)
bos.write(buf,0,len);
bos.close();
bis.close();
long end=System.currentTimeMillis();
System.out.println("Time:"+(end-start));//2216ms(复制的视频大小为500MB)
}
5. 处理流—转换流
- 转换流提供了在字节流和字符流之间的转换
InputStreamReader:将字节输入流转换为字符输入流
OutputStreamWriter:将字符输出流转换为字节输出流 - 构造器
OutputStreamWriter(OutputStream out) //创建一个使用默认字符编码的OutputStreamWriter
OutputStreamWriter(OutputStream out, Charset cs) //创建一个使用给定字符集的OutputStreamWriter。
InputStreamReader(InputStream in) //创建一个使用默认字符集的InputStreamReader
InputStreamReader(InputStream in, Charset cs) //创建一个使用给定字符集的InputStreamReader。
- 代码示例(将UTF-8编码的文件复制为GBK编码的文件)
public void test1() throws IOException
{
File Srcfile = new File("HelloWorld.txt");
File Destfile = new File("Copy.txt");
FileInputStream fis = new FileInputStream(Srcfile);
FileOutputStream fos = new FileOutputStream(Destfile);
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");
char[] buf=new char[5];
int len;
while((len=isr.read(buf))!=-1)
osw.write(buf,0,len);
isr.close();
osw.close();
}