Java IO之字节流与字符流操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34842671/article/details/81984731

Java中的流

  1. Java中的字节流
    InputStream是所有用于操作字节输入流的祖先类, OutputStream是所有用于操作字节输入流的祖先类,主要用来处理字节或二进制对象。

  2. Java中的字符流
    Reader用于读取字符输入流的祖先类,Writer是用于写入字符输出流的祖先类。它们的子类都需要实现read(或write)、flush和close方法,并通过重写若干方法提供更高效和多功能的输入输出操作。

四个祖先类都是抽象类,无法被直接new,需要通过创建其子类的实例来对字节流和字符流进行操作。

字节流与字符流的区别

  • 字节流
    字节流的处理单元为1个字节,操作字节和字节数组。字节流更加适用于音频文件、图片、歌曲,操作中文文本可能会出现乱码。字节流在操作过程中不会使用到缓冲区,直接对文件本身进行操作。

  • 字符流
    字符流的处理单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串。字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,因此对多国语言的支持性较好。字符流在操作的时候是需要使用到缓冲区的,因此需要使用close方法才能输出内容,或调用flush方法强制刷新缓冲区。

字节流的文件操作类

字节流操作类主要介绍FileInputStreamFileOutputStream两个类,这两个类分别继承InputStreamOutputStream,是字节流的文件操作实现类,读入和写出都有逐字节和按字节数组两种实现方式。字节流操作由于没有使用到缓冲区,所以不调用close方法也可以成功写入和读出。代码示例如下:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class BytesOperator {
    public static void main(String[] args) throws Exception{
        //读入
        File file = new File("D:\\Test.txt");
        FileInputStream inputStream = new FileInputStream(file);
        //逐字节读入
        int l = 0;
        while ((l = inputStream.read()) != -1) {
            System.out.println((char) l);
        }
        inputStream.close();
        //按字节数组读入
//        byte[] bytes = new byte[inputStream.available()];
//        inputStream.read(bytes);
//        String string = new String(bytes);
//        System.out.println(string);
//        inputStream.close();

        //写出
        File file2 = new File("D:\\result.txt");
        FileOutputStream outputStream = new FileOutputStream(file2);
        String test = "test1 test2";
        byte[] bytes2 = test.getBytes();
        //逐字节写出
        for(int i = 0; i < bytes2.length; i++) {
            outputStream.write(bytes2[i]);
        }
        outputStream.close();
        //按字节数组写出
//        outputStream.write(bytes2);
//        outputStream.close();
    }
}

字符流的文件操作类

InputStreamReader 是字节流与字符流之间的桥梁,可以读入字节流,并根据指定的编码方式转化成字符流。

OutputStreamWriter 是字符流与字节流之间的桥梁,可以从运行的程序中接收Unicode字符,然后使用指定的编码方式将字符流转化为字节流。

以上两个类都是字符流与字节流之间的桥梁,它们有转换的作用,其本身又是字符流,因此在构造时需要传入字节流对象。其使用的情况主要有如下两个:

  1. 源或者目的设备内部使用的是字节流,但操作的是文本数据;
  2. 操作文本时涉及具体编码表。

除了以上两个类以外,我们较为常用的还有FileReaderFileWriter,这两个类是InputStreamReaderOutputStreamWriter 的子类,也可以称为 convenience class(可译作方便类,大概就是说类的本身不提供任何方法,但是它提供操作其它类或者其它一系列类的简单入口,从类的继承关系图中也可以看出)。
FileReader 的继承关系如下图:
FileReader类继承关系
FileWriter 的继承关系如下图:
FileWriter类继承关系
FileReaderInputStreamReader 的主要区别在于FileReader的构造方法使用系统默认的字符编码和默认的字节缓存大小,如果需要指定这些值,可以通过传入一个FileInputStreamInputStreamReader进行构造。若操作Test.txt时使用的是系统默认的GBK,则以下两种读入字节流的代码意义相同。

//使用FileReader读入字节流
FileReader fr = new FileReader("D:\\Test.txt");
//使用InputStreamReader读入字节流
InputStreamReader sr = new InputStreamReader(newFileInputStream("D:\\Test.txt"));

若Test.txt中的字符数据是通过utf-8或者其他形式进行编码,则读取时必须指定编码表,只能使用 InputStreamReader,示例代码如下:

InputStreamReader sr = new InputStreamReader(new FileInputStream("D:\\Test.txt"), "UTF-8");

FileWriterInputStreamWriter 的主要区别与上述相类似,不再赘述,下面给出FileReaderFileWriter 的完整使用示例代码。

import java.io.*;

public class CharacterOperator {
    public static void main(String[] args) throws Exception{
        FileReader fr = new FileReader("D:\\Test.txt");
        //使用转换流指定编码表
//        FileInputStream inputStream = new FileInputStream("D:\\Test.txt");
//        InputStreamReader sr = new InputStreamReader(inputStream, "UTF-8");
        int l = 0;
        while ((l = fr.read()) != -1) {
            System.out.print((char) l);
        }
        fr.close();

        FileWriter fw = new FileWriter("D:\\result.txt");
        //使用转换流指定编码表
//        FileOutputStream outputStream = new FileOutputStream("D:\\result.txt");
//        OutputStreamWriter sr = new OutputStreamWriter(outputStream, "UTF-8");
        String test = "test1 test2 测试1";
        fw.write(test);
        fw.close();
    }
}

除了以上介绍的若干类之外,还有 BufferedReaderBufferedWriterReaderWriter 的子类,都可用于操作字符流,通过缓冲的方式实现字符、数组和行的高效读取,主要用于提高读取、写入的效率,在本文中不做讨论。

猜你喜欢

转载自blog.csdn.net/qq_34842671/article/details/81984731