廖雪峰Java6 IO编程-3Reader和Writer-1Reader
1.java.io.Reader和java.io.InputStream的区别
InputStream | Reader |
---|---|
字节流,以byte为单位 | 字符流,以char为单位 |
读取字节(-1,0-255):int read() | 读取字符,(-1,0-65535):int read() |
读到字节数组:int read(byte[] b) | 读到字符数组:int read(char[] c) |
int read(byte[] b, int off, int len) | int read(char[] c, int off, int len) |
2.Reader
java.io.Reader是所有字符输入流的超类:
- int read():
* 读取下一个字节,并返回字符的int值 (0-65535)
* 如果已读取到末尾,返回-1
* read()方法是阻塞(blocking)的,必须等待read()方法返回才能执行下一行代码 - int read(char[] c):读取若干字符并填充到char[]数组,返回读取的字符数
- int read(char[] c, int off, int len):指定char[]数组的偏移量和最大填充数
- void close():关闭Reader
2.1完整的读取一个Reader的所有字符:
方法1:手动关闭
方法2:使用try...finally
方法3:使用try(resource)自动关闭
public class Main {
public static void main(String[] args) throws IOException,ClassNotFoundException {
String file = "./src/main/java/com/testList/Person.txt";
readFile1(file);
System.out.println();
readFile2(file);
System.out.println();
readFile3(file);
}
static void readFile1(String file) throws IOException{
//手动关闭
Reader reader = new FileReader(file);
int n;
while((n=reader.read())!=-1){
System.out.print((char)n);
}
reader.close();
}
static void readFile2(String file) throws IOException{
//使用finally关闭
Reader reader = null;
try{
reader = new FileReader(file);
int n;
while((n=reader.read())!=-1){
System.out.print((char)n);
}
}finally {
if (reader!=null){
reader.close();
}
}
}
static void readFile3(String file) throws IOException{
//自动关闭
try(Reader reader = new FileReader(file)){
int n;
while((n=reader.read())!=-1){
System.out.print((char)n);
}
}
}
}
### 2.2利用缓冲区一次读取多个字符
read()单个返回char,利用竹筒则返回竹筒的长度
```#java
public static void main(String[] args) throws IOException,ClassNotFoundException {
String file = "./src/main/java/com/testList/Person.txt";
try(Reader reader = new FileReader(file)){
char[] buffer = new char[10];
int n;
while((n=reader.read(buffer))!= -1){
System.out.println(n);
}
}
}
```
### 2.3CharArrayReader可以在内存中模拟一个Reader
```#java
public static void main(String[] args) throws IOException,ClassNotFoundException {
char[] data = {'H','e','l','l','o'};
try(Reader reader = new CharArrayReader(data)){
int n;
while((n=reader.read())!=-1){
System.out.println((char)n);
}
}
}
```
## 3.Reader和InputSteam的关系
Reader实际上是基于InputStream构造的:
* FileReader内部持有一个FileInputStream
* Reader可以通过InputStream构造
```#java
InputStream input = new FileInputStreamReader(filename);
Reader reader = new InputStreamReader(input, "UTF-8");
...
reader.close();//当reader执行close时,会调用input的close方法关闭流。因此无需再针对input执行close方法
```
示例
```#java
public static void main(String[] args) throws IOException,ClassNotFoundException {
String file = "./src/main/java/com/testList/Person.txt";
try(Reader reader = new InputStreamReader(
new FileInputStream(file),"UTF-8")){
int n;
while((n=reader.read())!=-1){
System.out.print((char)n);
}
}
}
```
4.总结:
- Reader定义了所有字符输入流的超类
- FileReader实现了文件字符流输入
- CharArrayReader在内容中模拟一个字符流输入
- Reader是基于InputStream构造的:
* FileReader使用系统默认编码,无法指定编码
* 可以通过InputStreamReader指定编码 - 使用try(resource)保证Reader正确关闭