字符处理类Reader&Writer

1 、Reader与 Writer继承架构
针对字符数据的读取, Java SE提供了java.io. Reader类,其抽象化了字符数据读入的来源。针对字符数据的写入,则提供了java.io. Writer类,其抽象化了数据写出的目的地。如果想从来源读入字符数据,或将字符数据写至目的地,都可以使用下面的 CharUtil.dump()方法:

package intoutput;

import java.io.*;

public class CharUtil {
    public static void dump(Reader src, Writer dest) throws IOException {
        try (Reader input = src; Writer output = dest) {
            char[] data = new char[1024];
            int length;
            while ((length = input.read(data)) != -1) {
                output.write(data, 0, length);
            }
        }
    }
}

dump()方法接受 Reader与 Writer实例,分别代表读取数据的来源,以及输出数据的目的地。在进行 Reader与 Writer的相关操作时若发生错误,会抛出 IOException异常,在这里不特别处理,而是在dump()方法上声明 throws,由调用dump()方法的客户端处理。
在不使用Reader与 Writer时,必须使用 close()方法关闭串流。由于 reader与 Writer 操作了 closeable接口,其父接口为 Autocloseable接口,因此可使用JDK7尝试自动关闭资源语法。每次从 Reader读入的数据,都会先置入char数组中。 Reader的read()方法,每次会尝试读入char数组长度的数据,并返回实际读入的字符数,只要不是-1,就表示读取到字符目。可以使用 writer的 write()方法,指定要写出的byte数组、初始索引与数据长度。首先继承架构(图片来自网络):
这里写图片描述
这里写图片描述
从图得知, FileReader是一种 Reader,主要用于读取文档并将读到的数据转换为字符; stringwriter是一种 Writer,可以将字符数据写至
Stringwriter,最后使用 tostring()方法取得字符串,代表所有写入的字符数据。所以,若要使用CharUtil. dump()读入文档、转为字符串并显示在文本模式中,可以如下:

package intoutput;
import java.io.*;

public class CharUtilDemo {
    public static void main(String[] args) throws IOException {
        FileReader reader = new FileReader("B:\\test.txt");
        StringWriter writer = new StringWriter();
        CharUtil.dump(reader, writer);
        System.out.println(writer.toString());
    }
}

如果执行 CharUtilDemo时,在命令行自变量指定了文档位置,若文档中实际都是字符数据,就可以在文本模式中看到文档中的文字内容。
稍微解释一下几个常用的 Reader、 Writer子类。 StringReader可以将字符串打包,当作读取来源, stringWriter 则可以作为写入目的地,最后用 tostring()取得所有写入的字符组成的字符串。
CharArrayReader, CharArraywriter则类似,将char数组当作读取来源以及写入目的地。FileReader、 Filewriter可以对文档做读取与写入,读取或写入时默认会使用操作系统默认编码来做字符转换。也就是说,如果你的作系统默认编码是GB2312,则 FileReader、 Filewriter会以GB2312对你的“纯文本文档”做读取、写入的动作,如果操作系统默认编码是UTF-8,则 FileReader、 FileWriter就使用UTF-8
在启动JVM时,可以指定 -Dfile.encoding来指定 FileReader、 FileWriter所使用的编码。例如,指定使用UTF-8Java -Dfile.encoding=UTF-8 hello.intoutput.CharUtil test.txt
FileReader Filewriter没有可以指定编码的方法。如果在程序执行过程中想要指定编码,则必须使用InputstreamReader、 OutputstreamWriter,这两个类实际上作为装饰器。
2、字符处理装饰器
正如同 Inputstream、 OutputStream有一些装饰器类,可以对
InputStream. Outputstream打包增加额外功能, Reader、 Writer
也有一些装饰器类可供使用。下面介绍常用的字符处理装饰器类。
1. InputstreamReader 与OutputstreamWriter
如果串流处理的字节数据,实际上代表某些字符的编码数据,而你想要将这些字节数据转换为对应的编码字符,可以使用InputstreamReader,OutputStreamWriter对串流数据打包。改写CharUtil的dump()提供可指定编码的dump方法:

package intoutput;

import java.io.*;

public class CharUtil2 {
    public static void dump(Reader src, Writer dest) throws IOException {
        try (Reader input = src; Writer output = dest) {
            char[] data = new char[1024];
            int length;
            while ((length = input.read(data)) != -1) {
                output.write(data, 0, length);
            }
        }
    }

    public static void dump(InputStream src, OutputStream dest, String charset) throws IOException {
        dump(new InputStreamReader(src, charset), new OutputStreamWriter(dest, charset));
    }

    public static void dump(InputStream src, OutputStream dest) throws IOException {
        dump(src, dest, System.getProperty("file.encoding"));//采用默认编码
    }
}

调用:

CharUtil2.dump(new FileInputStream("B:\\test.xml"), new FileOutputStream("B:\\test.txt"), "UTF-8");

2. BufferedReader E Bufferedwriter
正如 BufferedInputstream, Bufferedoutputstream为Inputstream. Outputstream提供缓冲区作用,以改进输入输出的效率。BufferedReader, Bufferedwriter可对 Reader、 Writer提供缓冲区作用,在处理字符输入输出时,对效率也会有所帮助。

 BufferedReader reader =new BufferedReader(new InputStreamReader(System.in));//指定被打包的 Reader

创建 BufferedReader时要指定被打包的 Reader,可以指定或采用默认缓冲区大小。就API的使用而言, System.in是 Inputstream实例,可以指定给 InputstreamReader创建之用, InputstreamReader是一种 Reader,所以可指定给 BufferedReader创建之用。
就装饰器的作用而言,InputstreamReader将 System.in读入的字节数据做编码转换,而 BufferedReader将编码转换后的数据做缓冲处理,以增加读取效率。 BufferedReader的 readline()方法,可以读取一行数据(以换行字符为依据)并以字符串返回,返回的字符串不包括换行字符。
3. Printwriter
PrintWriter与PrintStream使用上极为类似,不过除了可以对OutputStream打包之外还可以对 Writer进行打包,提供 print()、 println()、 format()等方法。

猜你喜欢

转载自blog.csdn.net/zkd758/article/details/80152033
今日推荐