1.输入输出
InputStream和OutputStream是面向字节的,Reader和Write则面向字符的且兼容Unicode。
InputStream类型
ByteArrayInputStream:允许将内存的缓冲区当作InputStream使用
StringBufferInputStream:将String转换成InputStream
FileInputStream:用于从文件中读取信息
PipedInputStream:产生用于写入相关InputStreamOutputStream的数据。实现管道化概念
SequenceInputStream:将两个或多个InputStream对象转换成单一InputStream
FilterInputStream:抽象类,作为装饰器的接口
OutputStream类型
ByteArrayOutputStream:在内存中创建缓冲区,所有送往流的数据都要放置在此缓冲区
FileOutputStream:用于将信息写至文件
PipedOutputStream:任何写入其中的信息都会自动作为相关PipedInputStream的输出
FilterOutputStream:抽象类,作为装饰器的接口
FilterInputStream类型
DataInputStream:与DataOutputStream搭配使用,因此可以按照可移植方式从流读取基本数据类型
BufferedInputStream:使用它可以防止每次读取时都得到进行实际写操作。代表使用缓冲区
LineNumberInputStream:跟踪输入流中的行号;可调用getLineNumber()和setLineNumber(int)
PushbackInputStream:具有能弹出一个字节的缓冲区。因此可以将最后的最后一个字符回退
FilterOutputStream类型
DataOutputStream:与DataInputStream搭配使用,因此可以按照可移植方式从流写入基本数据类型
PrintStream:用于产生格式化输出。其中DataOutputStream处理数据的存储,PrintStream处理显示
BufferedOutputStream:使用它可以防止每次发送时都得到进行实际写操作。代表使用缓冲区
RandomAccessFile
RandomAccessFile是一个完全独立的类,直接从Object派生。
2.I/O流的使用
缓冲输入文件
如果想打开一个文件用于字符输入,可以用String或File对象作为文件名的FileInputStream,为了提高速度,对文件进行缓冲,将产生的引用传递给一个BufferedReader构造器。
String filename;
BufferedReader in = new BufferedReader(newFileReader(filename));
从内存输入
StringReader in = newStringReader(BufferedInputFile.read("MemoryInput.java"));
格式化的内存输入
要读取格式化数据,可使用DataInputStream。必须为ByteArrayInputStream提供字节数组。
DataInputStream in = newDataInputStream(new ByteArrayInputStream(BufferedInputFile.read("FormattedMemoryInput.java").getBytes()));
文件输出
FileWriter对象可以向文件写入数据。
String file = "BasicFileOutput.out";
PrintWriter out = new PrintWriter(newBufferedWriter(new FileWriter(file)));
文本文件输出的快捷方式
String file = "BasicFileOutput.out";
PrintWriter out = new PrintWriter(file);
存储和恢复数据
如果使用DataOutputStream写入数据,Java保证可以使用DataInputStream准确地读取数据,无论读和写数据的平台多么不同。
读写随机访问文件
RandomAccessFile除了实现DataInput和DataOutput接口,与I/O继承层次结构的其他部分实现了分离,RandomAccessFile不支持装饰,所以不能将其与InputStream和OutputStream子类的任何部分组合。
3.标准I/O
程序的所有输入都可以来自标准输入,它的所有的输出都可以发送到标准输出,以及所有的错误都可以发送到标准错误。
标准I/O的意义在于:可以很容易的把程序串联起来,一个程序的标准输出可以称为另一个程序的标准输入。
从标准输入中读取
按标准I/O模型,Java提供了System.in、System.out和System.err。其中System.out和System.err实现被包装成了printStream对象,System.in却是一个没有被包装过的未经加工的InputStream。即可以立即使用System.out和System.err,但在读取System.in之前必须对其进行包装。
将System.in包装成BufferedReader来使用,但这要求必须用InputStreamReader把System.in转换成Reader。
BufferedReader in = newBufferedReader(new InputStreamReader(System.in));
将System.out转换成PrintWriter
System.out是一个PrintStream,而PrintStream是一个OutputStream。PrintWriter有一个可以传参的构造器,因此使用哪个构造器把System.out转换成PrintWriter。
PrintWriter out = newPrintWriter(System.out, true);
标准I/O重定向
I/O重定向操作的是字节流,不是字符流;因此使用的是InputStream和OutputStream,而不是Reader和Writer。
4.新I/O
java.nio.*包引入新的Java I/O类库,其目的在于提高速度。速度提高来自于所使用的数据结构更接近操作系统执行I/O方式:通道和缓冲器。
唯一直接与通道交互的缓冲器是ByteBuffer,即可以存储未加工字节的缓冲器。
5.对象序列化
如果对象能够在程序不运行的情况下,仍能保存其运行信息,那么在下次运行时,该对象被重载并拥有的信息与程序上次运行时所拥有信息相同。当然,可以通过将信息写入文件或数据库来实现,但如果将一个对象声明为“持久性”,并处理所有细节,那将会十分方便。
Java的对象序列化是将那些实现了Serializable接口的对象转换成一个字节序列,并能够在以后将这个字节序列完全恢复为原来的对象。
利用对象序列化可以实现轻量级持久性。持久性意味着一个对象的生存周期不取决于程序是否正在执行,他可以生存于程序的调度之间。通过将一个序列化对象写入磁盘,然后在重新调用程序时恢复该对象,就能够实现持久性的效果。之所以称轻量级,是因为不能用某种关键字来简单地定义一个对象,并让系统自动维护其他细节问题。
Java对象序列化支持两种特性:
一是Java的远程方法调用(RMI),它使存活于其他计算机上的对象使用起来就像存活于本机上一项。
二是对Java Beans来说,对象序列化是必须的。使用一个Bean是,它的状态信息是在设计时进行配置,这种状态信息必须保存下来,并在程序启动时进行后期恢复,这种具体的工作就是有对象序列化完成的。
对象序列化:创建一个OutputStream,然后将其封装在一个ObjectOutputStream对象内,通过调用writeObject()方法即可将对象序列化
对象反序列化:创建一个InputStream,封装在ObjectInputStream内,调用readObject()方法