未分类

Java I/O简要笔记(一)——基础部分

因为以Android开发为主要目的,本篇博客的主要参考资料为Android Developers的文档。

Java I/O基础

Java I/O主要包括如下几个层次,包含三个部分:

  1. 流式部分――I/O的主体部分;
  2. 非流式部分――主要包含一些辅助流式部分的类,如:File类、RandomAccessFile类和FileDescriptor等类;
  3. 其他类–文件读取部分的与安全相关的类,如:SerializablePermission类,以及与本地操作系统相关的文件系统的类,如:FileSystem类和Win32FileSystem类和WinNTFileSystem类。

    IOStream Hierarchy
  • Java把数据传输这件事称为流。
  • Java 中的 I/O流类分为输入和输出部分。通过继承InputStreamReader的类都有read()方法,它可以读取单个字节或者字节数组。而继承OutputStreamWriter的类都有write()方法,它可以写入单个字节或者字节数组。一般通过组合多个对象来提供我们期望的功能(装饰器模式)。
  • Java的IO模型设计非常优秀,它使用Decorator(装饰器)模式,按功能划分Stream,可以动态装配这些Stream,以便获得需要的功能。例如,若需要一个具有缓冲的文件输入流,则应当组合使用FileInputStreamBufferedInputStream
  • Java中的InputStreamOutputSream提供基于字节的IO操作。
  • Java中的ReaderWriter以面向Unicode字符(16位,2个字节)的方式提供I/O功能。字符流的本质是基于字节流I/O时(调用了转换器)查了对应的码表。可以使用InputStreamReader以及OutputStreamWriter适配器将字符流转化为字节流。

    ==Tips:==适配器是连接不匹配的二者,让以上两者变匹配的对象。此处的两个适配器要把字符流转化为字节流,所以要在具备基础IO功能的基础上实现最基础的字符流的功能,而恰好ReaderWriter类是最基础的字符流,所以可以通过实现InputStreamOutputStream实现的接口+继承ReaderWriter类来实现转换。

字符流

Reader

  • Writer

  • 使用字符输出所用的抽象类,以下是子类必须实现的方法:
    1
    2
    3
    4
    5
    6
    public abstract void write(char[], int, int);//输出给定字符数组中从int起的int个字符
    public abstract void flush();
    //用于flush整条流。当本Writer在缓冲区里保存了字符时,立即将保存的字符都写入目的地,并且若目的地也是流,也flush它,由此可知flush()方法会清空整条流上的所有缓冲区
    //若目的地为文件,则flush方法保证缓冲区中的字符都交给操作系统作写入处理,但不保证字符确实被写入物理存储设备
    public abstract void close();//关闭本流,关闭前先flush它
    //对已经关闭的流执行write()或flush()方法会导致抛出IOException
OutputStreamWriter
  • 如前文所述是字符流转为字节流的适配器,可以指定编码或编码器,否则使用平台默认编码;未指定编码器时,对于无法映射的Unicode字符组统一使用编码的默认替代字符来替代。
  • 在将字符转为字节时,亦如前文所述,会调用转换器进行字符与字节的转换。而OutputStreamWriter会在向底层输出流写入转换完成的字符前将其存入缓冲区,减少了写入操作频率,提升效率。注意:输入的字符没有缓冲
    1
    2
    3
    public OutputStreamWriter(OutputStream)
    //可选重载参数:String charsetName, 指定的编码名;Charset csn, 指定的编码;
    //CharsetEncoder enc, 指定的编码器

==Tips:== 因为输入OutputStreamWriter的字符没有经过缓冲,为了实现最佳性能,推荐使用时在OutputStreamWriter外包装BufferedWriter

BufferedWriter
  • 提供适配不同环境的newLine()方法用于换行(并非所有平台均使用\n进行换行);
  • 在输出至字符流前会先将字符存入缓冲区,提升效率。
    1
    2
    public BufferedWriter(Writer)
    //可选重载参数:int sz,指定缓冲区大小
FileWriter
  • 写入文件用,使用默认编码和默认字节缓冲区大小(无字符缓冲,可通过包装BufferedWriter来改善性能)。若想改变编码,可在FileOutputStream上使用OutputStreamWriter
    1
    2
    3
    public FileWriter(String fileName)
    //重载参数:File
    //可选重载参数:boolean,true时为append模式

==Tips:== 某些平台只允许一个操作文件的对象(i.e.FileWriter)同时操作同一文件,容易导致抛出IOException。

PrintWriter
  • 输出格式化的文本。可以指定编码。该类中实现了PrintStream类中的所有print*方法以及format()方法。不提供字节输出。
  • 其构造函数包含可选boolean重载参数,值为true时开启自动刷新模式,即在每个print*方法被调用时执行flush()方法。(默认为当输出一个换行符\n时执行)
  • 除某些构造函数构造的对象外不会抛出IOException。需要手动调用checkError()方法,若返回true则说明在输出至流或在格式化字符串的过程中遇到错误。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public PrintWriter(Writer);
    //重载参数:OutputStream, File, String fileName.
    //可选重载参数:boolean,true时为自动刷新模式;String csn,指定的编码。

    public
    PrintWriter append(CharSequence csq)//等价于write(csq.toString()),受缓冲区的限制可能不能输出所有内容
    //其他重载没有此限制
    //若字符串为null,则输出"null"
    protected
    void clearError()//初始化checkError()检查的flag
分享到