欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java中的IO流

程序员文章站 2024-03-04 16:32:47
...

java中的I/O流

为什么需要I/O流

试想一下,当我们的服务需要从本地磁盘、网络…中读取或者写入大量数据的时候。但是我们的内存和带宽都是很有限的,无法一次性地读取大量地数据。
而流可以实现一点一点地逐步传输数据。当我们下载大文件地过程中,服务并不会占用很大地内存空间,而只是从内存中划分出一个缓冲区,当缓冲区满地时候再把数据flush到磁盘。

流是什么

通过流的形式允许java程序使用相同的方式来访问不同的输入/输出源;stream是从起源(source)到接收的(sink)的有序数据;我们这里把输入/输出源对比成水桶,那么流就是管道,这个管道的粗细、单向性等属性也就是区分了不同“流”的特性。

java中的IO流

I/O流的分类

java中的IO流

字符流和字节流

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