java I/O

一个极其庞大的I/O体系。

Java I/O 简介

Java I/O 将数据看作流(Stream),通过各种 IO 操作去处理不同的数据流。IO 体系如图所示:

Java 根据数据传输方式将 IO 类 分为两种:字节流和字符流,如上图所示。接下来按照上图中的结构进行介绍。

I/O 类

由于类与类之间有高度的对称性(如 FileInputStream、FileOutputStream),因此在介绍时将会把对称的类一起讲。

字节流与字符流的区别

字节流读取单个字节,字符流读取单个字符(一个字符根据编码的不同,对应的字节也不同,如 UTF-8 编码是 3 个字节,中文编码是 2 个字节。)字节流用来处理二进制文件(图片、MP3、视频文件),字符流用来处理文本文件(可以看做是特殊的二进制文件,使用了某种编码,人可以阅读)。简而言之,字节是个计算机看的,字符才是给人看的。

字节流

InputStream、OutputStream

这两个类是抽象类,包含一个最基本的方法read() / write(),具体的实现方法有下面的子类对象进行实现。以下列出几个其包含的方法:

InputStream OutputStream 介绍
public abstract int read() public abstract void write(int b) 读入/写出
public int read(byte b[]) public void write(byte b[]) 读入/写出 byte 数组
public void close() public void close() 读入/写出完,关闭数据流
public long skip(long n) 跳过指定个字节
public void flush() 强制刷新,将缓冲中的数据写入

根据场景的不同选择不同的子类,从子类的名称就能够看出来应用场景,比如ByteArrayInputStream表示读入一个 Byte 数组。

控制台输入 BufferedReader

BufferedReader 可用于读取控制台输出,其用法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 读取单个字符
//使用输入输出相关类时需要导入 java.io 包,java.io 包几乎包含了所有操作输入输出需要的类。
import java.io.*;

public class BRRead {
// 对于输入需要设置格式为 int read() throws IOException,输入时返回一个整数值,当流结束时返回 -1 ,并抛出一个 IOException 异常。
public static void main(String args[]) throws IOException {
char c;
// 使用 System.in 创建 BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("输入字符, 按下 'q' 键退出。");
// 使用 read() 方法读取字符
do {
c = (char) br.read();
System.out.println(c);
} while (c != 'q');
}
}
/*
output:
a
a
b
b
add
a
d
d


q
q
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//读入字符串
import java.io.*;

public class BRReadLines {

public static void main(String args[]) throws IOException {
// 使用 System.in 创建 BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str;
System.out.println("Enter lines of text.");
System.out.println("Enter 'end' to quit.");
// 使用 readLine() 方法读取字符串
do {
str = br.readLine();
System.out.println(str);
} while (!str.equals("end"));
}

}
/*
output:
test
test
First Line
First Line
last line
last line
end
end
*/

字符流

Reader、Writer

与字节流的两个类相似,这两个类也是抽象类,具体方法由子类实现。以下是其包含的几个方法:

Reader Writer 介绍
public int read() public void write(int c) 读入/写出单个字符
public int read(char cbuf[]) public void write(char cbuf[]) 读入/写出到指定数组
abstract public void close() abstract public void close() 关闭输入/输出流
public Writer append(CharSequence csq) 追加一个字符序列
abstract public void flush() 强制刷新,将缓冲中的数据写入

子类与字节流同理。

读写文件 FileInputStream/FileOutputStream

FileInputStream/FileOutputStream 用于读写文件,他的对象可用关键字 new 创建。

可由多种方法创建该对象,格式如下:

1
2
3
4
5
6
7
8
//使用文件名创建输入流对象
InputStream f = new FileInputStream("C:/java/hello");

//使用文件对象创建输入流对象
File f = new File("C:/java/hello");
InputStream out = new FileInputStream(f);

// FileOutputStream 同上

上述对象可用以下方法进行其他流操作:

FileInputStream FileOutputStream 介绍
public void close() throws IOException{} public void close() throws IOException{} 关闭输入/输出流,并抛出异常。
protected void finalize()throws IOException {} protected void finalize()throws IOException {} 清除与文件之间的连接,并抛出异常。
public int read(int r)throws IOException{} 从 InputStream 对象读取指定字节的数据。返回为整数值。返回下一字节数据,如果已经到结尾则返回-1。
public void write(int w)throws IOException{} 这个方法把指定的字节写到输出流中。
public void write(byte[] w) 把指定数组中w.length长度的字节写到OutputStream中。

下面是一个简单的文件读入读出的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.io.*;

public class fileStreamTest {
public static void main(String args[]) {
try {
byte bWrite[] = { 11, 21, 3, 40, 5 };

// 将 bwrite 数组写入到 test.txt
OutputStream os = new FileOutputStream("test.txt");
for (int x = 0; x < bWrite.length; x++) {
os.write(bWrite[x]);
}
os.close();

InputStream is = new FileInputStream("test.txt");
int size = is.available();// 返回可读的字节数

// 输出文件中内容
for (int i = 0; i < size; i++) {
System.out.print((char) is.read() + " ");
}
is.close();
} catch (IOException e) {
System.out.print("Exception");
}
}
}

能力有限,未完待续。。。

感谢您的支持
-------------本文结束感谢您的阅读-------------