API-5

基本IO操作

1.IO与OS

  • 输入与输出:
    • 什么是输入:
      • 输入是一个从外界进入到程序的方向,通常我们需要”读取”外界的数据时,使用到输入。所以输入是用来读取数据的。
    • 什么是输出:
      • 输出是一个从程序发送到外界的方向,通常我们需要”写出”数据到外界时,使用到输出。所以输出是用来写出数据的。

2.节点流与处理流

  • 按照流是否直接与特定的地方(如磁盘,内存,设备等)相连,分为节点流和处理流两类。
    • 节点流(低级流)
      • 可以从或向一个特定的地方(节点)读写数据。
    • 处理流(高级流或过滤流)
      • 是对一个已存在的流的连接与封装,通过已封装的流的功能调用实现数据读写。

3.IS和OS常用方法

  • InputStream是所有字节输入流的父类,其定义了基础的读取方法。
    • 方法:
      • int read():
        • 读取一个字节,以int形式返回,该int值的”低八位”有效,若返回值为-1则表示EOF。
      • int read(byte[] d):
        • 尝试最多读取给定数组length个字节并存入该数组,返回值为实际读取到的字节量。
  • OutputStream是所有字节输出流的父类,其定义了基础写出方法。
    • 方法:
      • void write(int d):
        • 写出一个字节,写的是给定的int的”低八位”
      • void write(byte[] d):
        • 将给定的字节数组中的所有字节全部写出
      • void write(byte[] d,int off,int len):
        • 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。

4.文件流

创建FOS对象(重写模式)
  • FlieOutputStream是文件的字节输出流,我们使用该流可以以字节为单位将数据写入文件
    • 构造方法:
      • FlieOutputStream(File file):
        • 创建一个向指定Flie对象表示的文件中写出数据的输出流
      • FlieOutputStream(String filename):
        • 创建一个向具有指定名称的文件中写出数据的输出流
  • 注意:
    • 若指定文件已经存在内容,使用Fos写入数据时,会将该文件中的数据覆盖。
创建FOS对象(追加模式)
  • 若想在原文件后追加新数据则需要用以下构造方法创建FOS。
    • 构造方法:
      • FlieOutputStream(File file,boolean append):
      • FlieOutputStream(String filename,boolean append):
        • 如第二个参数为true,通过该FOS写出的数据都是追加在文件原数据末尾写入的。
创建FIS对象
  • FlieInputStream是文件的字节输入流,使用该流可以以字节为单位从文件中读取数据。
    • 构造方法:
      • FlieInputStream(File file):
        • 创建一个从指定File对象表示的文件中读取数据的文件输入流
      • FlieInputStream(String filename):
        • 创建用于读取给定文件系统中的路径名name所指定的文件的文件输入流

5.缓冲流

  • BufferedOutputStream缓冲输出流内部维护着一个缓冲区,每当我们向该流写数据时,会先将数据存入缓冲区,当缓冲区已满时,缓冲流会将数据一次性全部写出。
  • BOS的flush方法

    • 使用缓冲输出流可以提高写出效率,但是有一个问题,就是写出数据缺乏即时性。因为数据都存在缓冲区,当缓冲区满时,缓冲流才会将数据写出。所以我们在执行完写出操作后,无法及时查看写出数据。这时我们就需要用到缓冲流的flush方法。
    • void flush():
      • 强制将当前缓冲流已缓存的字节一次性写出
      • 频繁调用flush会提高写出数据的频率,这会降低写出效率,但是会提高写出数据即时性。(按需求而定)
  • BufferedInputStream是缓冲字节输入流,其内部维护着一个缓充区(字节数组),该流在读取一个字节时,该流会尽可能多的一次性读取若干字节并存入缓冲区,然后逐一的将字节返回,直到缓冲区中的数据被全部读取完毕,会再次读取若干字节从而反复。这样就减少了读取的次数,从而提高了读取效率。

  • BIS是一个处理流,该流为我们提供了缓冲功能。

6.对象流

  • 对象序列化
    • 对象是存在内存中的。有时我们需要将对象保存到硬盘上,又有时我们需要经对象传到另一台计算机上,等等这样的操作,而这个过程就称作对象序列化。相反,我们有这样的一个字节序列需要将其转换为对应的对象,这个过程称为对象的反序列化。
  • ObjectPutputStream是用来对对象进行序列化的输出流。
    • 实现对象序列化方法:
      • void writeObject(Object o):
        • 可以将给定的对象转换为一个字节序列后写出。
  • ObjectInputStream是用来对对象进行反序列化的输入流。
    • 实现对象反序列化方法:
      • Object readObject():
        • 可以从流中读取字节并转换为对应的对象。

7.Serializable接口

  • 用于启动对象的序列化功能,可以强制让指定类具备序列化功能,该接口中没有成员,这是一个标记接口。这个标记接口用于给序列化类提供UID。这个uid是依据类中的成员的数字签名进行运行获取的。如果不需要自动获取一个uid,可以在类中,手动指定一个名称为serialVersionUID id号。依据编译器的不同,或者对信息的高度敏感性。最好每一个序列化的类都进行手动显示的UID的指定。

8.transient关键字

  1. transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。
  2. 被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
  3. 一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。也可以认为在将持久化的对象反序列化后,被transient修饰的变量将按照普通类成员变量一样被初始化。