计应本的自考笔记(7)-Java IO

261 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,[点击查看活动详情]

数据流的概念

程序离不开信息的输入输出,Java把不同类型的输入、输出源抽象为流(Stream),把输入/输出的数据成为数据流(Data Stream)。

数据流是一组有顺序的,有起点和终点的字节集合。又分为输入数据流和输出数据流,输入数据流只能读不能写,输出数据流只能写不能读。从数据流中读取数据时,必须有一个数据源与之相连。

java.io包提供了4个基本抽象类,InputStream、OutputStream、Reader、Writer。

输入流

输入流是只能读不能写的数据流,基于InputStream抽象类提供了一些列方法。从数据留读取数据,需要一个数据源与之连接。

// 访问输入流中数据的方法:当输入流读取结束后,会得到-1,标识数据流结束。
int read();
int read(byte[] b);
int read(byte[] b, int off, int len);

实际应用中,为提高效率,读取数据时,常以系统允许的最大数据块长度作为单位读取,也就是BufferInputeStream。

// 关闭数据流
void close();
// 返回可从数据流中读取的字节数
void available();
// 跳过数据流中指定数量的字节不读取
long skip();

由于数据流的读取是从头到尾顺序进行的,如果需要反向读取,则需要使用回推(Push Back)操作。

// 是否支持回推操作
boolean markSupported();
// 标记数据量当前位置
void mark();
// 重置
void reset();

输出流

输出数据流是从Java程序输出到计算机的数据,只能写不能读。

// 写入数据流:和输入流一样,通常以系统允许的最大数据块长度作为单位读取
void write();
void write(byte b[]);
void write(byte b[], int off, int len);
// 关闭输出流
void close();
// 刷新输出流,并强制写出所有缓冲的字节数据
void flush();

字节流

文件流

文件数据流主要通过FileInputStream和FileOutputStream两个类来处理,其数据源和数据终点都应该是文件。

值得注意的是,FileInputStream类的实例对象,如果所指定的文件不存在会产生FileNotFoundException异常,读写文件或生成新文件时发生错误会产生IOException,都需要加以捕获或声明。FileOutputStream类的实例,如果指定的文件不存在,则会创建新文件。如果存在,会覆盖文件原有的数据。

过滤器流

过滤器数据流在创建时,就与一个已存在的数据流相连,用于对该数据流进行特定处理

缓冲区

缓冲区数据流有BufferInputStream和BufferOutputStream,它们的作用是在原有数据流的基础上增加一个缓冲区。当读写数据时,数据以块为单位先进入缓冲区,后续读写数据都作用于缓冲区。从而降低不同硬件设备之间的速度差异,提高I/O效率。

基于数据类型的数据流

DataInputStream和DataOutputStream允许通过数据流来读写Java基础数据类型,包括boolean、float等。

但由于字符编码的原因,应该避免使用这些方法。比如对字符进行操作的时候,应该使用Reader和Writer类的方法进行操作。

对象流

Java不仅支持对基础数据类型进行读写,还支持把对象作为文件数据流进行读写。通过java.io的ObjectInputStream和ObjectOutputStream两个类实现。

序列化

将对象的状态记录存储起来,称为对象的持久化。

对象通过变量的数值来描述实例的状态,记录对象就是记录这些数值。将对象转换为字节序列的过程称为序列化,把字符序列恢复为对象的过程称为反序列化。如果变量值是另一个对象的引用,那么引用对象也要进行序列化,这个过程是递归的。

通过java.io.Serializable接口支持将Java对象进行序列化。序列化对象,必须与ObjectInputStream/ObjectOutputStream联系起来。前者使用readObject方法从输入流读取对象,后者用writeObject方法将对象保存到输出流。

虽然序列号只能保存对象的非静态成员变量的值,但有些对象涉及需要保密的数据,不希望存到永久介质当中的,可在变量前加transient关键字,表明该成员不适合进行序列化。

字符流

Reader和Writer

Java Reader和Writer也是抽象类,通过它们实现对不同平台之间的字符处理。使用的是Unicode字符集来表示字符串和字符。

Reader和Writer底下有InputStreamReader和OutputStreamWriter类

BufferReader和BufferWriter

字符流同样拥有缓冲区用以提升IO效率,分别是BufferReader和BufferWriter

文件处理

File

java.io.File提供对文件信息获取和操作文件的方法

  • 创建File对象
// 创建文件方法1
File myFile;
myFile = new File("myfile");

// 创建文件方法2
myFile = new File("/", "myfile");

// 创建文件方法3
File myDir = new File("/");
myFile = new File(myDir, "myfile");

随机访问文件

Java提供了RandonAccessFile随机访问文件

疑惑

  • 不实现Serializable接口,与@transient注解的区别