Java I/O streams
I/O Streams
Byte Streams
输入输出以字节为单位,所有的使用字节流的类都继承自 InputStream 和 OutputStream。
Byte Streams 属于 low-level I/O,其实是应该避免使用的,效率不高,之所以要提到 Byte Streams 是因为其他的 I/O 流是基于它实现的。
举例:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyBytes {
public static void main(String[] args) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("xanadu.txt");
out = new FileOutputStream("outagain.txt");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
} finally {
// 及时关闭流文件
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
机制如下:
Character Streams
Java 使用 Unicode 来存储字符值,字符流会自动转换该格式为本地字符集。
举例:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyCharacters {
public static void main(String[] args) throws IOException {
FileReader inputStream = null;
FileWriter outputStream = null;
try {
inputStream = new FileReader("xanadu.txt");
outputStream = new FileWriter("characteroutput.txt");
int c;
while ((c = inputStream.read()) != -1) {
outputStream.write(c);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}
CopyCharacters 的实现和 CopyBytes 非常像,只是其中的接口调用不太一样。在 CopyCharacters 中,int c 是一个字符的值至少 16bits,在 CopyBytes 中,int c 是一个字节值至少 8bits。
Character Streams 实际使用的是 Byte Streams,只是字符流会在 字符 与 字节 之间做一层自动的转化。
在 byte-to-character 转化时可以用到 InputStreamReader OutputStreamReader 这两个方法,在没有 prepackaged character 流中可以使用这些方法创建字符流。在 socket 中使用较多。
Line-Oriented I/O
以行为单位进行文件的读取与写入。
举例:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.IOException;
public class CopyLines {
public static void main(String[] args) throws IOException {
BufferedReader inputStream = null;
PrintWriter outputStream = null;
try {
inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));
String l;
// 读取每一行
while ((l = inputStream.readLine()) != null) {
// 以行方式写入
outputStream.println(l);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}
Buffered Streams
上面提到的几种流都是 unbuffered I/O,他们的每次读或者写都会直接调用底层的的接口进行读写,这样其实效率不高,并且一直触发硬盘的读写或者网络数据的读取或写入。为了提高效率,引入 buffered I/O ,对于写操话数据是优先被缓存起来,待 buffer 满的时候再写入硬盘,对于读操作,在 buffer 是空的时候会调用 input API(Buffered input streams read data from a memory area known as a buffer; the native input API is called only when the buffer is empty. Similarly, buffered output streams write data to a buffer, and the native output API is called only when the buffer is full.)。
对于一个不具有缓存的流可以转化成可缓存的流,如下:
inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new BufferedWriter(new FileWriter("characteroutput.txt"));
具有缓存功能的有以下几个类:
- BufferedInputStream (byte stream)
- BufferedOutputStream (byte stream)
- BufferedReader (character streams)
- BufferedWriter (character streams)
在特殊某些情况下,我们需要及时将缓冲中的数据进行写入,可以手动调用 flush() 来实现,但其实在 close() 的时候会调用 flush().
void flush()
throws IOException
Flushes this stream by writing any buffered output to the underlying stream.
Throws:
IOException - If an I/O error occurs
参考:
posted on 2017-09-21 15:11 vbirdchong 阅读(149) 评论(0) 编辑 收藏 举报