`
student_lp
  • 浏览: 429018 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多

四、字符流

 java提供了Reader和Writer两个专门操作字符流的类。

①Reader使用字符的方式从文件中读取数据。常用方法有:


 Reader是一个抽象类,具体可以完成的功能有其子类完成,如下:

CharArrayReader:直接从内存中以“字符”的形式读取数据。每次读取一个字符,存放到缓存区中。

FileReader:从文本文件中读取字符的字符输入流,该字符输入流使用系统默认的字符集编码和缓存区大小,不能更改。如果需要重新调整输入流的编码,必须使用InputStreamReader。

StringReader:从一个字符串中读取内容

BufferedReader:为其它的基于字符的输入流提供缓冲功能以提高效率。通常情况下,对于底层输入流的任何一次read或者readLine请求都将导致直接的磁盘访问,这将导致效率非常地下。

     当使用缓存的字符输入流时,读取请求将被缓存,在合适的时候一次性读入批量数据,再进行编码转换。以此显著提高效率。这个缓存输入流的缓冲区大小是可以指定的。

LineNumberReader:可以跟踪读入的“行数据”的字符输入流。该输入流内置一个指示器,用于跟踪读入的数据的行数。默认情况下行号从0开始。用户可以通过setLineNumber和getLineNumber来设置/或者行号。一个行可以由“换行符”,“回车符”,“回车换行符”标识。当遇到其中任意一个符号时,指示器的值将增加1。

     注意的是:setLineNumber方法并不会真正地改变数据在文件中的物理位置,而是简单地修改了指示器的数值而已。

②Writer是一个字符输出类。常用方法有:


writer也是一个抽象类,他的子类有:


PrintWriter:将对象数据以恰当的格式输出到文本输出流,和PrintOutputStream类不同,后者当碰到换行符的时候会清空缓冲区。但是PrintWriter不会,它只在print方法被调用时才会清空缓存。所以理论上来说它要比PrintOutputStream更加高效,因为只要缓冲区允许,它可以接纳更多的内容而一次性写入到文件。

      这个类使用系统默认的行分割符来代替“换行符"n”,因为不是所有的系统都是通过“"n”来换行的。

BufferedWriter:为其它字符输出流提供缓冲功能,该输出流的缓冲区大小可以设置,否则将使用默认的缓冲区大小。这个类有一个newLine方法,用于返回一个基于系统的行分割符,而非一定是“"n”。这个类会缓存写请求,当要写出的字符达到一定程度时就一次性地写出到底层的文件输出流。

CharArrayWriter:类似于ByteArrayOutputStream,向内存中写字符。其中内置一个缓冲区,大小可以动态增长。如果要得到写入的字符可以使用toCharArray方法,如果要构造出字符串则可以使用toString方法。

FileWriter:以基于字符的方式向文件中写数据。该输出流使用系统平台默认的字符集编码方式和缓存区大小,不能设置改变。如果需要的话可以使用OutputStreamWriter。

五、两种不同导向的 stream 之间的转换

      InputStreamReader 和 OutputStreamReader :把一个以字节为导向的 stream 转换成一个以字符为导向的 stream 。

      InputStreamReader 类是从字节流到字符流的桥梁:它读入字节,并根据指定的编码方式,将之转换为字符流。

      使用的编码方式可能由名称指定,或平台可接受的缺省编码方式。

      InputStreamReader 的 read() 方法之一的每次调用,可能促使从基本字节输入流中读取一个或多个字节。

      为了达到更高效率,考虑用 BufferedReader 封装 InputStreamReader ,BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

      OutputStreamWriter 将多个字符写入到一个输出流,根据指定的字符编码将多个字符转换为字节。

      每个 OutputStreamWriter 合并它自己的 CharToByteConverter, 因而是从字符流到字节流的桥梁。

六、Java IO的一般使用原则:

1、按数据来源(去向)分类:
①、是文件: FileInputStream, FileOutputStream, FileReader, FileWriter
②、是byte[]:ByteArrayInputStream, ByteArrayOutputStream
③、是Char[]: CharArrayReader, CharArrayWriter
④、是String: StringBufferInputStream, StringReader, StringWriter
⑤、网络数据流:InputStream, OutputStream, Reader, Writer

2、按是否格式化输出分:
①、要格式化输出:PrintStream, PrintWriter

3、按是否要缓冲分:
①、要缓冲:BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter

4、按数据格式分:
①、二进制格式(只要不能确定是纯文本的): InputStream, OutputStream及其所有带Stream结束的子类
②、纯文本格式(含纯英文与汉字或其他编码方式);Reader, Writer及其所有带Reader, Writer的子类

5、按输入输出分:
①、输入:Reader, InputStream类型的子类
②、输出:Writer, OutputStream类型的子类

6、特殊需要:
①、从Stream到Reader,Writer的转换类:InputStreamReader, OutputStreamWriter
②、对象输入输出:ObjectInputStream, ObjectOutputStream
③、进程间通信:PipeInputStream, PipeOutputStream, PipeReader, PipeWriter
④、合并输入:SequenceInputStream
⑤、更特殊的需要:PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader

决定使用哪个类以及它的构造进程的一般准则如下(不考虑特殊需要):
首先,考虑最原始的数据格式是什么: 原则4
第二,是输入还是输出:原则5
第三,是否需要转换流:原则6
第四,数据来源(去向)是什么:原则1
第五,是否要缓冲:原则3(特别注明:一定要注意的是readLine()是否有定义,有什么比read, write更特殊的输入或输出方法)
第六,是否要格式化输出:原则2

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics