java中的IO流
java中的I/O流
为什么需要I/O流
试想一下,当我们的服务需要从本地磁盘、网络…中读取或者写入大量数据的时候。但是我们的内存和带宽都是很有限的,无法一次性地读取大量地数据。
而流可以实现一点一点地逐步传输数据。当我们下载大文件地过程中,服务并不会占用很大地内存空间,而只是从内存中划分出一个缓冲区,当缓冲区满地时候再把数据flush到磁盘。
流是什么
通过流的形式允许java程序使用相同的方式来访问不同的输入/输出源;stream是从起源(source)到接收的(sink)的有序数据;我们这里把输入/输出源对比成水桶,那么流就是管道,这个管道的粗细、单向性等属性也就是区分了不同“流”的特性。
I/O流的分类
字符流和字节流
I/O 按照处理数据类型分为:字符流(Reader和Writer及其子类)和字节流(InputStream和outPutStream及其子类)。
字符流和字节流的用法几乎是一样的,它们的区别如下:
- 操作数据单元不同:字节流是以字节(8bit)为单位,字符流是以字符为单位,根据码表映射字符,一次可能读多个字节。
- 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
- 字节流在操作的时候本身是不会用到缓冲区的,是对文件本身的直接操作;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件。
输入流和输出流
对输入流只能进行读操作(InputStream和Reader以及它们的子类);对输出流只能进行写操作(OutputStream和Writer以及它们的子类)。
节点流和处理流
按照流的角色来分,可以分为节点流和处理流。
节点流也称为低级流。使用节点流进行输入/输出时,程序直接连接到实际的数据流,和实际的输入/输出节点连接。
处理流也被称为高级流。处理流则用于对一个已存在的流进行连接或封装,通过封装后的流来实现数据读写功能,可以更加灵活方便地读写各种类型的数据。
节点流
类型 | 字符流 | 字节流 |
---|---|---|
File | FileReader、FileWriter | FileInputStream、FileOutputStream |
Memory Array | CharArrayReader、CharArrayWriter | ByteArrayInputStream、ByteArrayOutputStream |
Memory String | StringReader、StringWriter | StringBufferInputStream、StringBufferOutputStream |
Pipe | PipedReader、PipedWriter | PipedInputStream、PipedOutputStream |
处理流
类型 | 字符流 | 字节流 |
---|---|---|
Buffer | BufferedReader、BufferedWriter | BufferedInputStream、BufferedOutputStream |
Filter | FilterReader、FilterWriter | FilterInputStream、FilterOutputStream |
Converter | InputStreamReader、OutputStreamWriter | |
Object Serialization | ObjectInputStream、ObjectOutputStream | |
DataConversion | DataInputStream、DataOutputStream | |
Counting | LineNumberReader | LineNumberInputStream |
Peeking Ahead | PushbackReader | PushbackInputStream |
Printing | PrintWriter | PrintStream |
- Buffer缓冲流:在读入或写出时,对数据进行缓存,以减少I/O的次数
- Filter滤流:在数据进行读或写时进行过滤
- Converter转换流:按照一定的编码/解码标准将字节流转换为字符流(Stream到Reader)
- DataConversion数据流:按基本数据类型读、写(处理的数据是Java的基本类型,如布尔型,字节,整数和浮点数)
- Counting计数流:在读入数据时对行记数
- Peeking Ahead预读流:通过缓存机制,进行预读
- Printing打印流:包含方便的打印方法
缓冲流
对I/O进行缓冲是一种常见的性能优化,缓冲流为I/O流增加了内存缓冲区,增加缓冲区的两个目的:
- 允许Java的I/O一次不只操作一个字符,提高整个系统的性能.
- 由于有缓冲区,使得在流上执行skip、mark和reset方法都成为可能。
- “套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率
case
FileInputStream & FileOutputStream
private static void cpFile(String src, String dest) {
InputStream in = new FileInputStream(src);
OutputStream os = new FileOutputStream(dest);
int data = in.read();
while (data != -1) {
os.write(data);
data = in.read();
}
in.close();
os.close();
}
// 利用缓冲区
private static void cpFile1(String src, String dest) {
InputStream in = new FileInputStream(src);
OutputStream os = new FileOutputStream(dest);
byte[] buffer = new byte[2048];
int len = in.read(buffer);
while (len != -1) {
os.write(buffer, 0, len);
len = in.read(buffer);
}
in.close();
os.close();
}
DataInputStream & DataOutputStream
// 向文件中写入java基本数据类型
private void write(String dest) {
DataOutputStream os = new DataOutputStream(new FileOutputStream(dest));
os.writeInt(10);
os.writeChar('a');
os.writeChar('b');
os.writeDouble(12.83);
os.close();
}
// 从文件中读取java基本数据类型,和写入的顺序保持一致
private void read(String src) {
DataInputStream in = new DataInputStream(new FileInputStream(src));
int a = in.readInt();
char b = in.readChar();
char c = in.readChar();
double d = in.readDouble();
in.close();
}
BufferedInputStream & BufferedOutputStream
private void cpFile(String src, String dest) {
InputStream in = new BufferedInputStream(new FileInputStream(src));
OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));
int data = in.read();
while (data != -1) {
os.write(data);
data = in.read();
}
in.close();
os.close();
}
InputStreamReader & OutputStreamWriter
// 一次拷贝一个 字符
private void cpFile(String src, String dest) {
Reader reader = new InputStreamReader(new FileInputStream(src));
Writer writer = new OutputStreamWriter(new FileOutputStream(dest));
int data = reader.read();
while (data != -1) {
writer.write(data);
data = reader.read();
}
reader.close();
writer.close();
}
FileReader & FileWriter
private void cpFile(String src, String dest) {
Reader reader = new FileReader(src);
Writer writer = new FileWriter(dest);
int data = reader.read();
while (data != -1) {
writer.write(data);
data = reader.read();
}
reader.close();
writer.close();
}
BufferedReader & BufferedWriter
private void cpFile(String src, String dest) {
Reader reader = new BufferedReader(new FileReader(src));
Writer writer = new BufferedWriter(new FileWriter(dest));
int data = reader.read();
while (data != -1) {
writer.write(data);
data = reader.read();
}
reader.close();
writer.close();
}
上一篇: Java一维数组的使用
下一篇: Android事件的分发机制详解