java中的InputStream、OutputStream以及Reader、Writer

      Java中I/O操作主要是指使用Java进行输入,输出操作。Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列。在JavaAPI中,可以从其中读入一个字节序列的对象称作输入流;可以向其中写入一个字节序列的对象称作输出流。

      在Java.io包中,操作文件内容主要有两大类:字节流与字符流,两类都分为输入与输出操作。在字节流中,输入操作主要是使用InputStream完成,输出操作主要是使用OutputStream完成;在字符流中,输出主要是使用Writer完成,输入主要是使用Reader完成。我们存储在磁盘中的文件都是以字节存储来完成的,那些文件中的字符都是先编码成字节,然后再存储到磁盘中。在读取文件时(特别是文本文件),也是一个字节一个字节地读取以形成字节序列。由于面向字节的流不便于处理Unicode形式(Unicode中每个字符都使用了多个字节来表示)存储的信息,所以从抽象类Reader和Writer中继承出来的专门用于处理Unicode字符的类。字符流处理的单元为2个字节的Unicode字符,而字节流处理单元为1个字节,所以处理中文文本,用字符流好点,但是如果处理的是音频文件、图片、歌曲,就还是用字节流好点(因为这些文件在磁盘上的存储是字节,如果用字符去读的话,涉及到转换问题,会损坏原文件)。

     InputStream是一个抽象类,是所有数据形式为字节的输入流的父类,为基于字节的数据输入定义了基本操作方法。实际上,InputStream的子类大部分都没有增加其任何其他的接口函数。其子类有FileInputStream、StringBufferInputStream、FilterInputStream等。FileInputStream用于顺序访问本地文件,用于读取诸如图像数据之类的原始字节流,从超类InputStream中继承了read,close等方法,对文件进行操作,它的两个常用的构造方法是:FileInputStream(String filePath/*文件的全称路径*/); FileInputStream(File fileObj/*描述该文件的File对象*/);StringBufferInputStream类的本意是把字符串转换为字节流,然后进行读操作,但是在这个类中仅仅使用了字符编码的低8位,不能把字符串中的所有字符正确转换为字节,因此这个类被废弃,取而代之的是StringReader类;FilterInputStream是为了提高读取效率和经常用的读取类型,从而通过嵌套过滤器来添加多重功能,其实例化参数是InputStream,所以是在InputStream的基础上增强一些功能。

    FilterInputStream下比较常用的子类有BufferedInputStream、DataInputStream、PushBackInputStream等。BufferedInputStream的数据成员buf是一个位数组,默认字节为2048字节。当读取数据来源时,BufferedInputStream会尽量将buf填满,当使用read()方法时,实际上是先读取buf中的数据,而不是直接对数据源作读取。当buf中的数据不足时,BufferedInputStream才会再实现给定的InputStream对象的read()方法,从指定装置中提取数据,其实这也用到了操作系统中的局部原理。DataInputSteam主要是借用InputStream通过类型转换实现readInt,readBoolean功能。PushbackInputStream主要提供可以将数据插入到输入流前端的能力,能够插入的最大字节数与推回缓冲区的大小相关。

             BufferedInputStream 定义方式为:      InputStream in=new BufferedInputStream(new FileInputStream(fileName));

             DataInputStream 定义方式为:            DataInputStream din=new DataInputStream(new FileInputStream(fileName));

    OutputStream的用法与InputStream的用法类似,这里就不再多说!

     Reader是所有数据形式为字符的输入流的父类,其子类有BufferedReader、CharArrayReader、FilterReader、InputStreamReader和StringReader等。BufferedReader主要是从字符流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取,其最大特点就是缓冲区的设置,通常reader所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求,如果没有缓冲,每次调用read()或readLine()都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的。使用BufferedReader可以指定缓冲区的大小,或者可以使用默认的大小。InputStreamReader是字节流通向字符流的桥梁:它使用指定的charset读取字节并将其解码为字符,它使用的字符集可以由名称指定或显示给定,或者接受平台默认的字符集。构造方法主要有InputStreamReader(InputStream in)、InputStreamReader(InpuStream in,CharSet cs)等。每次调用InputStreamReader中的一个read()方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作的字节,为了达到最高效率,可以考虑在BufferedReader内包装InputStreamReader。例如:

           BufferedReader in=new BufferedReader(new InpuStreamReader(System.in))

    Writer的方法类似于Reader,这里不再多说!

   总体来说,整个java.io的核心都是采用了Decorator(装饰)模式,理解了Decorator(装饰)模式,对java I/O的学习就更加容易了。建议大家在学习时,将java.io的类结构图打印出来,在以后使用时再拿出来看下,就知道如何使用了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值