Stream,Reader/Writer,Buffered的区别
Posted 金洪光
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Stream,Reader/Writer,Buffered的区别相关的知识,希望对你有一定的参考价值。
Reader:
Reader的子类:
1.BufferedReader:
FileReader 没有提供读取文本行的功能,BufferedReader能够指定缓冲区大小,包装了read方法高效读取字符流。提供字符、数组和行的高效读取。
开发文档中的介绍:
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
通常,Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求。
因此,建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader(如 FileReader 和 InputStreamReader)。
例如,
BufferedReader in = new BufferedReader(new FileReader("foo.in"));
将缓冲指定文件的输入。如果没有缓冲,则每次调用 read() 或 readLine() 都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的。
通过用合适的 BufferedReader 替代每个 DataInputStream,可以对将 DataInputStream 用于文字输入的程序进行本地化。
构造方法摘要 |
BufferedReader(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流。 |
BufferedReader(Reader in, int sz) 创建一个使用指定大小输入缓冲区的缓冲字符输入流。 |
用途:
我只想说FileReader不要直接用,放到BufferedReader 再用。这样对于读取大文本文件节省时间。因为有缓冲文本文件,如果不缓冲的话会通过read方法一次又一次的访问文本文件。
2.LineNumberReader:
用法与BufferedReade一样,就是有个独特的方法,setLineNumber(int)
和 getLineNumber()
。
public class LineNumberReader extends BufferedReader
开发文档中的介绍:
跟踪行号的缓冲字符输入流。此类定义了方法 setLineNumber(int)
和 getLineNumber()
,它们可分别用于设置和获取当前行号。
默认情况下,行编号从 0 开始。该行号随数据读取在每个行结束符处递增,并且可以通过调用 setLineNumber(int)
更改行号。
但要注意的是,setLineNumber(int)
不会实际更改流中的当前位置;它只更改将由 getLineNumber() 返回的值。
可认为行在遇到以下符号之一时结束:换行符(\'\\n\')、回车符(\'\\r\')、回车后紧跟换行符。
构造方法摘要 |
LineNumberReader(Reader in) 使用默认输入缓冲区的大小创建新的行编号 reader。 |
LineNumberReader(Reader in, int sz) 创建新的行编号 reader,将字符读入给定大小的缓冲区。 |
3. InputStreamReader
字节流通向字符流的桥梁,一般结合BufferedReader使用。
你可以在构造器重指定编码的方式,如果不指定的话将采用底层操作系统的默认编码方式,可能在不同的平台上出现乱码现象!
当要指定编码方式时,必须使用InputStreamReader类。而不是用子类FileReader。
开发文档中的介绍:
InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset
读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。
为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
构造方法摘要 |
InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。 |
InputStreamReader(InputStream in, Charset cs) 创建使用给定字符集的 InputStreamReader。 |
InputStreamReader(InputStream in, CharsetDecoder dec) 创建使用给定字符集解码器的 InputStreamReader。 |
InputStreamReader(InputStream in, String charsetName) 创建使用指定字符集的 InputStreamReader。 |
4. FileReader
public class FileReader extends InputStreamReader
这个也是与InputStreamReader一样。区别就在于构造函数上。
当要指定编码方式时,必须使用InputStreamReader类。
开发文档中的介绍:
用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。
要自己指定这些值,可以先在 FileInputStream 上构造一个 InputStreamReader。
FileReader
用于读取字符流。要读取原始字节流,请考虑使用 FileInputStream
。
构造方法摘要 |
FileReader(File file) 在给定从中读取数据的 File 的情况下创建一个新 FileReader。 |
FileReader(FileDescriptor fd) 在给定从中读取数据的 FileDescriptor 的情况下创建一个新 FileReader。 |
FileReader(String fileName) 在给定从中读取数据的文件名的情况下创建一个新 FileReader。 |
Writer
Writer的子类:
很明显Writer是与Reader对应的,Reader是用来字符读出操作,Writer是用来字符写入操作。
就说明一个PrintWriter:
PrintStrean是写入一串8bit的数据的。
PrintWriter是写入一串16bit的数据的。
PrintStream是用来操作byte,
PrintWriter是用来操作Unicode,
PrintStream是OutputStream的子类,PrintWriter是Writer的子类.
我们常用的System.out变量就是PrintStream实例. 与之对应的字符流类是PrintWriter类.
开发文档中的介绍:
向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream
中的所有 print 方法。它不包含用于写入原始字节的方法,对于这些字节,程序应该使用未编码的字节流进行写入。
与 PrintStream
类不同,如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作,而不是每当正好输出换行符时才完成。这些方法使用平台自有的行分隔符概念,而不是换行符。
此类中的方法不会抛出 I/O 异常,尽管其某些构造方法可能抛出异常。客户端可能会查询调用 checkError()
是否出现错误。
构造方法摘要 |
PrintWriter(File file) 使用指定文件创建不具有自动行刷新的新 PrintWriter。 |
PrintWriter(File file, String csn) 创建具有指定文件和字符集且不带自动刷行新的新 PrintWriter。 |
PrintWriter(OutputStream out) 根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。 |
PrintWriter(OutputStream out, boolean autoFlush) 通过现有的 OutputStream 创建新的 PrintWriter。 |
PrintWriter(String fileName) 创建具有指定文件名称且不带自动行刷新的新 PrintWriter。 |
PrintWriter(String fileName, String csn) 创建具有指定文件名称和字符集且不带自动行刷新的新 PrintWriter。 |
PrintWriter(Writer out) 创建不带自动行刷新的新 PrintWriter。 |
PrintWriter(Writer out, boolean autoFlush) 创建新 PrintWriter。 |
以上是关于Stream,Reader/Writer,Buffered的区别的主要内容,如果未能解决你的问题,请参考以下文章
系统学习 Java IO (十三)----字符读写 Reader/Writer 及其常用子类