在Java语言中,将用于信息输入输出的流(I/O流)定义成了类,存放在java.io包中。按照流处理的对象,可将输入输出流分为字节输入输出流、字符输入输出流、对象输入输出流。
(一)Java语言中最基本的两个输入输出类 InputStream和OutputStream。其他所有字节输入输出流类都继承自这两个基类。这两个类是抽象类,因而不能创建它们的实例,只能使用它们的子类。Java字节输入输出流的类层次结构图如图(1)和图(2)所示.
图(1)InputStream类及其子类的层次和继承关系
图(2)OutputStream类及其子类的层次和继承关系
在InputStream类中,提供了许多方法。其中最主要的是3个read()方法。
方法1:
public abstract int read();
从输入流中读取一个字节,并将字节值以0~255之间的一个整数值返回。如果没有可读取的字节,则返回-1。该方法是一个抽象方法,其子类必须实现该方法。
方法2:
public int read(byte[] b);
从输入流中读取多个字节,读取的内容存放在缓冲字节数组b中。它将实际读取的字节术作为返回值。使用该方法必须保证数组有足够的空间存放数据,否则会抛出异常。
方法3:
public int read(byte[] b, int off, int len);
从输入流中读入长度为len的字节数据,并将读入的内容存放在缓冲字节数组b中从off开始的位置。
InputStream中其他的有关输入流的方法。skip()、available()和close()方法。
public long skip(long n);
从输入流中跳过n个字节。
public void available();
获取当前输入流中可以读入的字节数。
public void close();
关闭当前输入流。
同样,在OutputStream类中也有3个write()方法。
方法1:
public abstract void write(int b);
想输出流中写入一个字节。在Java中int类型是32位,这个方法会将整数b的低8位输出,而忽略高24位。
方法2:
public void write(byte[] b); 向输出流中写入b.length(b数组的长度)个字节。
public void write(byte[] b, int off, int len); 向输出流中写入b数组中从off位置开始的len字节。
在Java中标准的输入设备是键盘,标准的输出设备是显示器。它们分别对应System类中的变量in、out和err。这3个变量在System类中的声明如下:
public static final InputStream in;
public static final OutputStream out;
public static final PrintStream err;(二)在Java中,定了专门用于处理字符数据输入输出的抽象类(Reader和Writer类)。它们与InputStream和OutputStream类很相似,也有很多子类,用于处理字符数据的输入输出。字符输入输出流的类层次结构图如图(3)和图(4)所示.
图(3)Reader类的层次和继承关系
图(4)Writer类的层次和继承关系
常用字符输入输出流的说明如下表格:
| 类名 | 描述 |
| Reader | 读字符流的抽象类 |
| StringReader | 一个数据源是字符串的字符流 |
| CharArrayReader | 该类实现字符流读入时的字符缓冲 |
| FilterReader | 抽象类,用于读取过滤字符流 |
| InputStreamReader | 该类将输入的字节流转变为字符流 |
| PipedReader | 管道字符输入流 |
| Writer | 写字符流的抽象类 |
| CharArrayWriter | 该类在输出时实现字符缓冲 |
| FilterWriter | 用于输入过滤字符流的抽象类 |
| OutputStreamWriter | 讲输出的字符流转变为字节流 |
| PipedWriter | 管道字符输出流 |
| PrintWriter | 打印格式化对象内容到文本输出流中 |
| StringWriter | 该流将输入字符存放在一个字符串缓冲中,可以用来构造字符串 |
Reader类是用于读取字符流的抽象类。子类必须实现的方法只有read(char [], int, int)和close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率或其他功能。Reader类的相关方法如下表格所示:
| 方法名 | 方法的含义 |
| abstract void close() | 关闭流 |
| int read() | 读取单个字符 |
| int read(char []cbuf) | 将字符读入数组 |
| int read(charbuffer target) | 试图将字符读入指定的字符缓冲区 |
| void reset() | 重置该流 |
| long skip(long n) | 跳过字符 |
| void mark(int readAheadLimit) | 标记流中的当前位置 |
Writer类是写入字符流的抽象类。子类必须实现的方法仅有write(char [], int, int)、flush()和close()。但是多数子类将重写此处定义的一些方法,以提供更高的效率或其他功能。Writer类的相关方法如下表所示:
| 方法名 | 方法的含义 |
| Writer append(char c) | 将指定字符添加到writer |
| abstract void close() | 关闭此流,但先刷新它 |
| abstract void flush() | 刷新此流 |
| void write(char [] cbuf) | 写入字符数组 |
| void write(int c) | 写入单个字符 |
| void write(String str) | 写入字符串 |
(三)缓冲读写类
1.利用BufferedWriter输出字符数据
BufferedReader从字符输入流中读取文本,其构造方法如下:
public BufferedReader(Reader in);
利用BufferedReader类可以从字节型流(如System.in)中读取字符数据。Java提供了一个将字节流转换成子符流的类InputStreamReader类。其构造方法如下: public InputStreamReader(InputStream in);
因此使用如下方法声明BufferedReader对象,就可以使用BufferedReader对象具有从字节数据中取出字符数据的能力。利用BufferedReader还可以读取文本文件中的字符数据,但BufferedReader无法直接和文本文件关联,必须通过一个桥梁类FileReader。FileReader类的构造方法如下:
public FileReader(String filename) throws FileNotFoundException
public FileReader(File file) throws FileNotFoundException
FileReader类在BufferedReader流和实际数据文件之间起连接作用。利用如下方法声明的BufferedReader对象能够读取文本文件中的字符数据。 BufferedReader reader = new BufferedReader(new FileReader("filename"));2..利用BufferedWriter输出字符数据
BufferedWriter类用来创建一个字符输出流。该类提供了以字符的形式写数据的方法。Java中BufferedWriter类的构造方法如下:
public BufferedWriter(Writer out);
利用BufferedWriter可以向文本文件中写入字符数据,但BufferedWriter无法直接与文本文件建立连接,必须通过FileWriter类把BufferedWriter流与文本文件关联起来。FileWriter类的构造方法如下:
public FileWriter(File file) throws IOException
public FileWriter(String filename) throws IOException
public FileWriter(String filename, boolean append) throws IOException 以如下方式构造的BufferedWriter对象可以向文本文件中写入字符数据。
BufferedWriter writer = new BufferedWriter(new FileWriter("filename"));
利用PrintWriter类和BufferedWriter类结合可以将各种类型数据以字符形式保存到文本文件中。PrintWriter类的方法不会抛出任何异常,只能使用checkError()方法来检查是否发生了错误,其构造方法如下:
public PrintWriter(Writer out);
public PrintWriter(Writer out, boolean autoFlush);(四)文件写入类
FileReader是用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。要自己指定这些值,可以先在FileInputStream上构造一个InputStreamReader。FileReader类方法摘要如下表所示:
| 从类java.io.InputStreamReader继承的方法 | close,getEncoding,read,ready |
| 从类java.io.Reader继承的方法 | mark,markSupported,read,reset,skip |
| 从类java.lang.Object继承的方法 | clone,equals,toString,wait |
FileWriter类可用来写入字符数据的文件类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。要指定这些值,可以先在FileOutputStream上构造一个OutputStreamWriter。文件是否可用或是否可以被创建取决于系统平台。某些平台一次只允许一个FileWriter(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。FileWriter类方法摘要如下表所示:
| 从类java.io.OutputStreamReader继承的方法 | close,getEncoding,flush,write |
| 从类java.io.Writer继承的方法 | append,write |
| 从类java.lang.Object继承的方法 | clone,equals,toString,wait |
(五)格式化写类
PrintWriter类的作用是向文本输出流打印对象的格式化表示形式。
(六)对象序列化
Java的对象序列化将那些实现了Serializable接口的对象转换成一个字节序列,并且能够将这个字节序列完成恢复为原来的对象。对象序列化后的可以保存在磁盘上,这样在下次程序运行时就可以恢复该对象,完全持久性的效果。序列化以后的对象可以在网络上传输,使得不同的计算机可以共享对象。
Serializable接口是一个没有声明任何方法的接口。某个类实现Serializable接口主要是为了能将这个类的对象写入到ObjectOutputStream流中,并且可以通过ObjectInputStream流读取这些对象。在Java中,已经有很多类实现了Serializable接口,如Integer、Double、String等,其他类只要在声明时实现该接口,该类就可以被序列化。
1.对象输入流
ObjectInputStream对以前使用ObjectOutputStream写入的基本数据和对象进行反序列化。用于恢复那些以前序列化的对象。ObejctInputStream类的主要方法如下表所示:
| 方法名 | 方法的含义 |
| void close() | 关闭输入流 |
| int read() | 读取数据字节 |
| int read(char []cbuf) | 将字符读入数组 |
| int read(charbuffer target) | 试图将字符读入指定的字符缓冲区 |
| void reset() | 重置该流 |
| long skip(long n) | 跳过字符 |
| void mark(int readAheadLimit) | 标记流中的当前位置 |
2.对象输出流
Java I/O 流详解
257

被折叠的 条评论
为什么被折叠?



