字符编码格式:按照什么样的标准去将字符编码。比如GBK、UTF-8等等。
因为java程序经常操作一些文本文件,这些文件里面存放的是字符,而这些字符是进行了一些编码的,为了快速读取这些编码过的字符,java专门提供了对字符进行操作的流,叫字符流。
为了读取各种字符编码格式的字符,java中提供了字符流,它可以读取带文本的文本文档内容。等于是说它把字节流进行了一个包装,变成了字符流。
字符输入流
Reader也是抽象类,其常用子类是InputStreamReader(是Reader的子类,是FileReader的父类),FileReader,BufferedReader。
FileReader
构造方法:
new FileReader(File file)
new FileReader(String path)
用FileReader读取文本文档:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo {
public static void main(String[] args) {
FileReader fr = null;
try {
fr = new FileReader("H:/demo.txt");
char[] c = new char[4];
int length = fr.read(c);
while (length != 0) {
for (int i = 0; i < length; i++) {
System.out.print(c[i]);
}
length = fr.read(c);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
1、在上面这个程序中,有一个挺有意思的事情:就是这个while循环。
while (length != 0) {
for (int i = 0; i < length; i++) {
System.out.print(c[i]);
}
length = fr.read(c);
}
当我把while循环的判断条件写为:length != 0
的时候,在最后的屏幕输出界面我需要手动去终止结果。而当条件为length != -1
的时候,程序会自动终止。原因在于int read(char [] c)
这个方法。当没有读到字符流末尾时,返回的是读取到的字符的长度,当读取到 输入流的末尾的时候,返回的值是-1;所以如果把判断条件写为不等于0,则会陷入到死循环当中,需要手动去终止程序。
2、同时使用StringBuffer可以简化输出的过程,代码如下:
fr = new FileReader("H:/demo.txt");
StringBuffer s = new StringBuffer();
char[] c = new char[4];
int length = fr.read(c);
while (length != -1) {
s.append(c);
length = fr.read(c);
}
System.out.println(s);
这种方式是借用StringBuffer的一个方法,这个方法可以直接在StringBuffer类型的数据后面追加一个字符数组。最后直接输出这个StringBuffer类型的数据就可以了。
但是这个方法也存在问题:当字符数组长度设为其他数字时,最后可能会多东西,因为上一次数组读的东西并没有消失,如果没有被完全覆盖的话,在最后可能会被追加。并且如果数组长度定义的太长的话,最后会出现大量空格。所以可以使用append的一个重载方法:append(char[], int i, int length)前一个int是开始位置,后一个位置是要从开始位置添加的长度。如下:
fr = new FileReader("H:/demo.txt");
StringBuffer s = new StringBuffer();
char[] c = new char[8];
int length = fr.read(c);
while (length != -1) {
s.append(c, 0, length);
length = fr.read(c);
}
System.out.println(s);
3、乱码的问题
只要是在中文的windows系统下,默认的文本文档格式都是ANIS,这个格式可以看做是GBK。而MyEclipse也有默认的文本文档编码格式,可以在windows-preference-General-Workspace中找到。当你系统默认的文本编码格式和IDE环境设置的文本编码格式不一致时,就会出现乱码。乱码可能出现在结果中和代码程序注释中。
乱码问题解决方式如下:
一、保持IDE环境的字符编码格式和文本文档的字符编码格式一致,可以改变IDE环境的字符编码格式,也可以把文本文档另存为新的字符编码格式。
二、字符流去读的时候,指定字符流的编码格式。而FileReader无法指定编码格式,会按照系统默认的编码格式System.getProperty("file.encoding")
(获取系统默认编码格式)来读。此时可以采用InputStreamReader来进行读取,并在读取的时候指定编码格式。
InputStreamReader(是Reader的子类,是FileReader的父类)
构造方法:
new InputStreamReader(InputStream)
new InputStreamReader(InputStream. String charSetName)
第一种方式是传了一个字节流进来,第二种方式在传进来一个字节流的同时指定编码格式(将流的编码格式设置的跟文件的编码格式一致时,就不会出现乱码了)。
缓冲流BufferedReader
该类是Reader类的子类,带有缓冲区,有按行读取内容的readLine()方法,该方法返回读取的字符。
缓冲流的机制:相当于字符流带了缓冲区,先把一批数据读到缓冲区里面,然后再从缓冲区里面去读东西,可以提高读取效率。
构造方法:
new BufferedReader(Reader)
BufferedReader的构造方法需要一个Reader类型的参数,而InputStreamReader和FileReader都是Reader的子类,所以可以把这两个类型的数据作为参数传进去,这样相当于把这两个类型的数据包成一个BufferedReader类型,提高读取效率。
注:带缓冲区的流有时候会读不出来东西,这时候可能的原因是:流没有关。