java.io 字符流

字符串基类

java.io 包中专门用于字符流处理的类,是以Reader和Writer为基础派生的一系列类

字符串以字符为单位,根据码表映射字符,一次可能读多个字节,只能处理字符类型的数据。

同类InputStream 和 OutputStream一样,Reader 和 Writer 也是抽象类,只提供了一系列用于字符流处理的接口。他们的方法与类InputStream 和 OutputStream类似,只不过其中的参数换成字符或字符数组

Reader 是所有的输入字符流的父类,他是一个抽象类

我们先来看一看基类 Reader 的方法,其用法与作用都与InputStream 和 OutputStream 类似,就不做过多的说明了

方法 返回值
close() void
mark(int readAheadLimit) void
markSupported() boolean
read() int
rerad(char[] cbuf,int off,int len) int
ready() boolean
reset() void
skip(long n) long

Writer 是所有的输出字符流的父类,它是一个抽象类。Writer的方法:

方法 返回值
close() void
flush() void
write(char[] cbuf) void
write(char[] cbuf, int off,int len) void
write(int c) void
write(String str) void
write(String str, int off, int len) void

转换流

InputStreamReader 和 OutputStreamWriter 是 java.io 包中用于处理字符流的最基本的类,用来在字节流和字符流之间作为中介:从字节输入流读入字节,并按编码规范转换为字符;往字节输出流写字符时先将字符按编码规范转换为字节。使用这两者进行字符处理时,在构造方法中应指定一定的平台规范,以便把以字节方式表示的流转换为特定平台上的字符表示。

1
2
3
4
5
6
7
8
9
InputStreamReader(InputStream in); //缺省规范说明

//指定规范 enc
InputStreamReader(InputStream in, String enc);

OutputStreamWriter(OutputStream out); //缺省规范说明

//指定规范 enc
OutputStreamWriter(OutputStream out, String enc);

如果读取的字符流不是来自本地时(比如网上某处与本地编码方式不同的机器),那么在构造字符输入流时就不能简单地使用缺省编码规范,而应该指定一种统一的编码规范“ISO 8859_1”,这是一种映射到 ASCCII 码的编码方式,能够在不同平台之间正确转换字符。

1
InputStreamReader ir = new InputStreamReader(is,"8859_1");

缓冲流

类 BufferedInputStream 和 BufferedOutputStream 实现了带缓冲的过滤流,它提供了缓冲机制,把任意的 I/O 流“捆绑”到缓冲流上,可以提高 I/O 流的读取效率。

在初始化时,除了要指定所连接的 I/O 流之外,还可以指定缓冲区的大小。缺省时是用 32 字节大小的缓冲区;最优的缓冲区大小常依赖于主机操作系统、可使用的内存空间以及机器的配置等;一般缓冲区的大小为内存页或磁盘块等的整数倍。

BufferedInputStream 的数据成员 buf 是一个位数组,默认为 2048 字节。当读取数据来源时例如文件,BufferedInputStream 会尽量将 buf 填满。当使用 read() 方法时,实际上是先读取 buf 中的数据,而不是直接对数据来源作读取。当 buf 中的数据不足时,BufferedInputStream 才会再实现给定的 InputStream 对象的 read() 方法,从指定的装置中提取数据。

BufferedOutputStream 的数据成员 buf 是一个位数组,默认为 512 字节。当使用 write() 方法写入数据时,实际上会先将数据写至 buf 中,当 buf 已满时才会实现给定的 OutputStream 对象的 write() 方法,将 buf 数据写至目的地,而不是每次都对目的地作写入的动作。

构造方法:

1
2
3
4
//[ ]里的内容代表可选参数
BufferedInputStream(InputStream in [, int size])
BufferedOutputStream(OutputStream out [, int size])

举个例子,将缓冲流与文件流相接:

1
2
3
4
5
6
7
8
9
10
FileInputStream in = new FileInputStream("file.txt");
FileOutputStream out = new FileOutputStream("file2.txt");

//设置输入缓冲区大小为256字节
BufferedInputStream bin = new BufferedInputStream(in,256)
BufferedOutputStream bout = new BufferedOutputStream(out,256)

int len;
byte bArray[] = new byte[256];
len = bin.read(bArray); //len 中得到的是实际读取的长度,bArray 中得到的是数据

缓冲流示例图

对于 BufferedOutputStream,只有缓冲区满时,才会将数据真正送到输出流,但可以使用 flush() 方法人为地将尚未填满的缓冲区中的数据送出。

例如方法 copy():

1
2
3
4
5
6
7
8
9
10
11
public void copy(InputStream in, OutputStream out) throws IOException {
out = new BufferedOutputStream(out, 4096);
byte[] buf = new byte[4096];
int len = in.read(buf);
while (len != -1) {
out.write(buf, 0, len);
len = in.read(buf);
}
//最后一次读取得数据可能不到4096字节
out.flush();
}

BufferedReader 和 BufferedWrite

同样的,为了提高字符流处理的效率,java.io 中也提供了缓冲流 BufferedReader 和 BufferedWrite。其构造方法与 BufferedInputStream 和 BufferedOutPutStream 相类似。另外,除了 read() 和 write() 方法外,它还提供了整行字符处理方法:

  1. public String readLine() : BufferedReader 的方法,从输入流中读取一行字符,行结束标志 \n 、**\r** 或者两者在一起(这是根据系统而定的)
  2. public void newLine() : BufferedWriter 的方法,向输出流中写入一个行结束标志,它不是简单地换行符 \n\r , 而是系统定义的行隔离标志(line separator)

看一看例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class FileToUnicode {
public static void main(String args[]) {
try {
FileInputStream fis = new FileInputStream("file1.txt");
InputStreamReader dis = new InputStreamReader(fis);
BufferedReader reader = new BufferedReader(dis);
String s;
//每次读取一行,当改行为空时结束
while((s = reader.readLine()) != null){
System.out.println("read:" + s);
}
dis.close();
}
catch(IOException e) {
System.out.println(e);
}
}
}

如file1.txt 的内容如下:

1
2
3
abc
efg
hij

输出结果:

1
2
3
4
5
$ javac FileToUnicode.java
$ java FileToUnicode
read:abc
read:efg
read:hij

其他字符流类

在这里我们就列举一下有哪些类,具体的就不仔细列举了。

  1. 对字符数组进行处理: CharArrayReader、CharArrayWrite
  2. 对文本文件进行处理:FileReader、FileWriter
  3. 对字符串进行处理:StringReader、StringWriter
  4. 过滤字符流:FilterReader、FileterWriter
  5. 管道字符流:PipedReader、PipedWriter
  6. 行处理字符流:LineNumberReader
  7. 打印字符流:PrintWriter

类有千万,方法更是不计其数,所以没有必要去掌握所有的方法和类,只需要知道常见常用的就行了,而大多数的类和方法,希望大家有一个印象,当我们在实际开放的时间,能够想到,并且借助其他工具去查询我们需要的方法的应用方式就可以了。

参考链接