Java IO原理
- I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。
- Java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行。
- java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。
![JavaIO流原理](https://img-blog.csdnimg.cn/20200328095248977.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2dsZGJ5cw==,size_16,color_FFFFFF,t_70)
流的分类
- 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)
- 按数据流的流向不同分为:输入流,输出流
- 按流的角色的不同分为:节点流,处理流
抽象基类 | 字节流----------字符流 |
---|
输入流 | InputStream----------Reader |
输出流 | OutputStream----------Writer |
![流的分类](https://img-blog.csdnimg.cn/20200328095802499.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2dsZGJ5cw==,size_16,color_FFFFFF,t_70)
IO流体系
![IO流体系](https://img-blog.csdnimg.cn/2020032809590271.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2dsZGJ5cw==,size_16,color_FFFFFF,t_70)
节点流和处理流
- 节点流:直接从数据源或目的地读写数据
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200328100200789.png)
- 处理流:不直接连接到数据源或目的地,而是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供强大的读写功能。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200328100215875.png)
InputStream & Reader
- InputStream 和 Reader 是所有输入流的基类。
- InputStream(典型实现:FileInputStream)
int read()
int read(byte[] b)
int read(byte[] b, int off, int len) - Reader(典型实现:FileReader)
int read()
int read(char [] c)
int read(char [] c, int off, int len) - 程序中打开的文件 IO 资源不属于内存里的资源,垃圾回收机制无法回收该资源,所以应该显式关闭文件 IO 资源。
- FileInputStream 从文件系统中的某个文件中获得输入字节。FileInputStream 用于读取非文本数据之类的原始字节流。要读取字符流,需要使用 FileReader
InputStream
- int read()
从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。 - int read(byte[] b)
从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。否则以整数形式返回实际读取的字节数。 - int read(byte[] b, int off,int len)
将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len 个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。如果因为流位于文件末尾而没有可用的字节,则返回值 -1。 - public void close() throws IOException
关闭此输入流并释放与该流关联的所有系统资源。
OutputStream & Writer
- OutputStream 和 Writer 也非常相似:
void write(int b/int c);
void write(byte[] b/char[] cbuf);
void write(byte[] b/char[] buff, int off, int len);
void flush();
void close(); 需要先刷新,再关闭此流 - 因为字符流直接以字符作为操作单位,所以 Writer 可以用字符串来替换字符数组,即以 String 对象作为参数
void write(String str);
void write(String str, int off, int len); - FileOutputStream 从文件系统中的某个文件中获得输出字节。FileOutputStream 用于写出非文本数据之类的原始字节流。要写出字符流,需要使用 FileWriter
OutputStream
- void write(int b)
将指定的字节写入此输出流。write 的常规协定是:向输出流写入一个字节。要写入的字节是参数 b 的八个低位。b 的 24 个高位将被忽略。 即写入0~255范围的。 - void write(byte[] b)
将 b.length 个字节从指定的 byte 数组写入此输出流。write(b) 的常规协定是:应该与调用write(b, 0, b.length) 的效果完全相同。 - void write(byte[] b,int off,int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。 - public void flush()throws IOException
刷新此输出流并强制写出所有缓冲的输出字节,调用此方法指示应将这些字节立即写入它们预期的目标。 - public void close() throws IOException
关闭此输出流并释放与该流关联的所有系统资源。
缓冲流
- 为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。
- 缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:
BufferedInputStream 和 BufferedOutputStream
BufferedReader 和 BufferedWriter
1 当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲区
2 当使用BufferedInputStream读取字节文件时,BufferedInputStream会一次性从文件中读8192个(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中读取下一个8192个字节数组。
3 向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满,BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法flush()可以强制将缓冲区的内容全部写入输出流
4 关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也会相应关闭内层节点流
5 flush()方法的使用:手动将buffer中内容写入文件
6 如果是带缓冲区的流对象的close()方法,不但会关闭流,还会在关闭流之前刷新缓冲区,关闭后不能再写出
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200328101157914.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2dsZGJ5cw==,size_16,color_FFFFFF,t_70)
流的分类:
1 操作数据单位:字节流,字符流
2 数据的流向:输入流,输出流
3 流的角色: 节点流,处理流
二,流的体系结构
抽象基类 节点流(或文件流) 缓冲流(处理流的一种)
InputStream FileInputStream BufferedInputStream
OutputStream FileOutputStream BufferedOutputStream
Reader FileReader BufferedReader
Writer FileWriter BufferedWriter
package BYSSSExer2;
import org.junit.Test;
import java.io.*;
public class BufferedTest {
@Test
public void BufferedStreamTest() throws IOException {
long l = System.currentTimeMillis();
File srcFile = new File("cxy.jpg");
File destFile = new File("cxy3.jpg");
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] buffer = new byte[10];
int len;
while ((len = bis.read(buffer))!=-1){
bos.write(buffer,0,len);
}
bos.close();
bis.close();
fos.close();
fis.close();
long l1 = System.currentTimeMillis();
System.out.println(l1-l);
}
public void copyFileWithBuffered(String srcPath,String destpath) throws IOException {
File srcFile = new File(srcPath);
File destFile = new File(destpath);
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] buffer = new byte[10];
int len;
while ((len = bis.read(buffer))!=-1){
bos.write(buffer,0,len);
}
bos.close();
bis.close();
fos.close();
fis.close();
}
@Test
public void testcopyFileWithBUfferd() throws IOException {
String srcPath = "cxy.jpg";
String destPath = "cxy4.jpg";
copyFileWithBuffered(srcPath,destPath);
}
@Test
public void testBufferedReaderBufferedWriter() throws IOException {
File srcFile1 = new File("hello.txt");
File destFile1 = new File("hello4.txt");
FileReader fr = new FileReader(srcFile1);
FileWriter fw = new FileWriter(destFile1);
BufferedReader br = new BufferedReader(fr);
BufferedWriter bw = new BufferedWriter(fw);
BufferedReader br = new BufferedReader(new FileReader(new File("hello.txt")));
BufferedWriter bw = new BufferedWriter(new FileWriter(new File("hello4.txt")));
char[] cbuf =new char[5];
int len;
while ((len=br.read(cbuf))!=-1){
bw.write(cbuf,0,len);
}
String data;
while ((data = br.readLine())!=null){
bw.write(data);
bw.write(data+"\n");
bw.write(data);
bw.newLine();
}
bw.close();
br.close();
}
}
package BYSSSExer2;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileInputOutputStreamTest {
@Test
public void testFileInputStream() throws IOException {
File file = new File("hello.txt");
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[5];
int len;
while ((len = fis.read(buffer))!=-1){
String str = new String(buffer,0,len);
System.out.print(str);
}
fis.close();
}
@Test
public void testFileInputOutputStream() throws IOException {
File srcfile = new File("cxy.jpg");
File destfile = new File("cxy1.jpg");
FileInputStream fis = new FileInputStream(srcfile);
FileOutputStream fos = new FileOutputStream(destfile);
byte[] buffer = new byte[5];
int len;
while ((len = fis.read(buffer))!=-1){
fos.write(buffer,0,len);
}
fis.close();
fos.close();
}
}