← 返回首页
JavaSE系列教程(七十二)
发表时间:2020-02-21 01:01:17
讲解java IO流之字符流。

字符流是专门用来读写字符文件的流。字符流所处理的数据基本单元是字符,其输入输出操作都是在字符的基础上进行,Java语言中的字符采用Unicode字符编码,每个字符占2个字节空间,而文本文件有可能采用其它类型的编码,如GBK,UTF8编码方式,因此有时需要字符编码之间的转换。

字符流常见的操作接口类如下:

其中,Reader和Writer是两个抽象类不能直接实例,必须实例化它们的子类。而FileReader/FileWriter和BufferedReader/BufferedWriter分别是它们的子类。

1.FileReader和FileWriter实现文件读写

++Reader最常用的方法如下:++

public abstract int read() throws IOException;:抽象方法。从输入流读取单个字符,返回所读取的字符数据(字符数据可直接转换为int类型)。返回-1表示到了输入流的结束点。

public int read(char b[], int off, int len) throws IOException:从输入流中最多读取len个字符的数据,并将其存储在数组b中,放入数组b时,并不是从数组起点开始,而是从off位置开始,返回实际(实际长度可能小于len)读取的字符数。返回-1表示到了输入流的结束点。

public int read(char b[]) throws IOException:从输入流中最多读取b.length个字符的数据,并将其存储在数组b中,返回实际读取的字符数。相当于调用read(b, 0, b.length)。返回-1表示到了输入流的结束点。

++Writer最常用方法如下:++ public abstract void write(int b) throws IOException;:将指定的一个字符输出到输出流中,此处b表示一个字符。

public void write(char b[], int off, int len) throws IOException:将字符数组中从off位置开始,长度为len的字符输出到输出流中。

public void write(char b[]) throws IOException:将字符数组中的数据输出到指定输出流中。相当于调了write(b, 0, b.length)。

实例:使用字符流实现一个java源文件的复制每次读写一个字符并统计总用时多少毫秒。

    public static void main(String[] args) {

        Reader bin = null;
        Writer bout = null;
        File srcFile = new File("D:"+File.separator+"MyUtils.java");
        File destFile = new File("E:"+File.separator+"MyUtils.java");
        try{
            bin = new FileReader(srcFile);
            bout = new FileWriter(destFile);
            long startTime = System.currentTimeMillis();
            int ch=-1;
            while((ch=bin.read())!=-1){ //每次读出一个字符
                bout.write(ch); //写入一个字符
            }
            long endTime = System.currentTimeMillis();
            System.out.println("总用时:"+(endTime - startTime)+"毫秒");
        }catch(Exception ex){
            ex.printStackTrace();
        }finally{
            try {
                if(bin!=null) {
                    bin.close();
                    bin = null;
                }
                if(bout!=null) {
                    bout.close();
                    bout = null;
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }

    }

运行结果:
总用时:30毫秒

2.BufferedReader和BufferedWriter

BufferedReader和BufferedWriter 是带缓冲的输入和输出流可以大大提升读写效率。因为BufferedReader和BufferedWriter比Reader和Writer多出了readLine()和write(String)方法,可以按行读写。

注意:readLine()方法返回的是不带换行符号的一行字符串内容,因此在写入时必须手工拼上换行回车字符或者使用newLine()方法。

把上面的java源文件复制的例子改写为使用带缓冲的流实现。

    public static void main(String[] args) {

        BufferedReader bin = null;
        BufferedWriter bout = null;
        File srcFile = new File("D:"+File.separator+"MyUtils.java");
        File destFile = new File("E:"+File.separator+"MyUtils.java");
        try{
            bin = new BufferedReader(new FileReader(srcFile));
            bout = new BufferedWriter(new FileWriter(destFile));
            long startTime = System.currentTimeMillis();
            String s=null;
            while((s=bin.readLine())!=null) { //一次读出一行字符串
                bout.write(s+"\r\n"); //一次写入一行,后面手工拼上行号回车转义字符。
                //或者使用bout.newLine();
            }

            long endTime = System.currentTimeMillis();
            System.out.println("总用时:"+(endTime - startTime)+"毫秒");
        }catch(Exception ex){
            ex.printStackTrace();
        }finally{
            try {
                if(bin!=null) {
                    bin.close();
                    bin = null;
                }
                if(bout!=null) {
                    bout.close();
                    bout = null;
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }

    }

运行结果:
总用时:3毫秒

3.InputStreamReader和OutputStreamWriter

InputStreamReader和OutputStreamWriter可以实现字节流转换为字符流。 例如:上面的java源文件复制的例子改写为使用字节流转字符流实现。

    public static void main(String[] args) {

        BufferedReader bin = null;
        BufferedWriter bout = null;

        File srcFile = new File("D:"+File.separator+"MyUtils.java");
        File destFile = new File("E:"+File.separator+"MyUtils.java");
        try{
            //因为是字节流转字符流有可能出现中文乱码,必须指定正确的字符编码格式。
            bin = new BufferedReader(new InputStreamReader(new FileInputStream(srcFile),"utf-8"));
            bout = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destFile),"utf-8"));

            long startTime = System.currentTimeMillis();
            String s=null;
            while((s=bin.readLine())!=null) {
                bout.write(s+"\r\n");
            }

            long endTime = System.currentTimeMillis();
            System.out.println("总用时:"+(endTime - startTime)+"毫秒");
        }catch(Exception ex){
            ex.printStackTrace();
        }finally{
            try {
                if(bin!=null) {
                    bin.close();
                    bin = null;
                }
                if(bout!=null) {
                    bout.close();
                    bout = null;
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }

    }

运行结果:
总用时:3毫秒