基本IO操作
1.IO与OS
- 输入与输出:
- 什么是输入:
- 输入是一个从外界进入到程序的方向,通常我们需要”读取”外界的数据时,使用到输入。所以输入是用来读取数据的。
- 什么是输出:
- 输出是一个从程序发送到外界的方向,通常我们需要”写出”数据到外界时,使用到输出。所以输出是用来写出数据的。
- 什么是输入:
2.节点流与处理流
- 按照流是否直接与特定的地方(如磁盘,内存,设备等)相连,分为节点流和处理流两类。
- 节点流(低级流)
- 可以从或向一个特定的地方(节点)读写数据。
- 处理流(高级流或过滤流)
- 是对一个已存在的流的连接与封装,通过已封装的流的功能调用实现数据读写。
- 节点流(低级流)
3.IS和OS常用方法
- InputStream是所有字节输入流的父类,其定义了基础的读取方法。
- 方法:
- int read():
- 读取一个字节,以int形式返回,该int值的”低八位”有效,若返回值为-1则表示EOF。
- int read(byte[] d):
- 尝试最多读取给定数组length个字节并存入该数组,返回值为实际读取到的字节量。
- int read():
- 方法:
- OutputStream是所有字节输出流的父类,其定义了基础写出方法。
- 方法:
- void write(int d):
- 写出一个字节,写的是给定的int的”低八位”
- void write(byte[] d):
- 将给定的字节数组中的所有字节全部写出
- void write(byte[] d,int off,int len):
- 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。
- void write(int d):
- 方法:
4.文件流
创建FOS对象(重写模式)
- FlieOutputStream是文件的字节输出流,我们使用该流可以以字节为单位将数据写入文件
- 构造方法:
- FlieOutputStream(File file):
- 创建一个向指定Flie对象表示的文件中写出数据的输出流
- FlieOutputStream(String filename):
- 创建一个向具有指定名称的文件中写出数据的输出流
- FlieOutputStream(File file):
- 构造方法:
- 注意:
- 若指定文件已经存在内容,使用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所指定的文件的文件输入流
- FlieInputStream(File file):
- 构造方法:
5.缓冲流
- BufferedOutputStream缓冲输出流内部维护着一个缓冲区,每当我们向该流写数据时,会先将数据存入缓冲区,当缓冲区已满时,缓冲流会将数据一次性全部写出。
BOS的flush方法
- 使用缓冲输出流可以提高写出效率,但是有一个问题,就是写出数据缺乏即时性。因为数据都存在缓冲区,当缓冲区满时,缓冲流才会将数据写出。所以我们在执行完写出操作后,无法及时查看写出数据。这时我们就需要用到缓冲流的flush方法。
- void flush():
- 强制将当前缓冲流已缓存的字节一次性写出
- 频繁调用flush会提高写出数据的频率,这会降低写出效率,但是会提高写出数据即时性。(按需求而定)
BufferedInputStream是缓冲字节输入流,其内部维护着一个缓充区(字节数组),该流在读取一个字节时,该流会尽可能多的一次性读取若干字节并存入缓冲区,然后逐一的将字节返回,直到缓冲区中的数据被全部读取完毕,会再次读取若干字节从而反复。这样就减少了读取的次数,从而提高了读取效率。
- BIS是一个处理流,该流为我们提供了缓冲功能。
6.对象流
- 对象序列化
- 对象是存在内存中的。有时我们需要将对象保存到硬盘上,又有时我们需要经对象传到另一台计算机上,等等这样的操作,而这个过程就称作对象序列化。相反,我们有这样的一个字节序列需要将其转换为对应的对象,这个过程称为对象的反序列化。
- ObjectPutputStream是用来对对象进行序列化的输出流。
- 实现对象序列化方法:
- void writeObject(Object o):
- 可以将给定的对象转换为一个字节序列后写出。
- void writeObject(Object o):
- 实现对象序列化方法:
- ObjectInputStream是用来对对象进行反序列化的输入流。
- 实现对象反序列化方法:
- Object readObject():
- 可以从流中读取字节并转换为对应的对象。
- Object readObject():
- 实现对象反序列化方法:
7.Serializable接口
- 用于启动对象的序列化功能,可以强制让指定类具备序列化功能,该接口中没有成员,这是一个标记接口。这个标记接口用于给序列化类提供UID。这个uid是依据类中的成员的数字签名进行运行获取的。如果不需要自动获取一个uid,可以在类中,手动指定一个名称为serialVersionUID id号。依据编译器的不同,或者对信息的高度敏感性。最好每一个序列化的类都进行手动显示的UID的指定。
8.transient关键字
- transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。
- 被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
- 一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。也可以认为在将持久化的对象反序列化后,被transient修饰的变量将按照普通类成员变量一样被初始化。