黑马程序员—IO流学习小结(2)(Java)
----------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
续前
四、 Java的IO字符流编程基础
1. 字节流在读中文的时候有可能会读到半个中文,造成乱码 ,字节流直接操作的字节,所以写出中文必须将字符串转换成字节数组。
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("zzz.txt");
fos.write("我读书少,你不要骗我".getBytes());
fos.write("\r\n".getBytes());
fos.close();
}
2. 字符流是可以直接读写字符的IO流,字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要写出字符, 需要把字符转为字节再写出。
1)FileReader类的read()方法可以按照字符大小读取中文,返回值为int,如果已到达流的末尾,则返回 -1。
FileReader fr = new FileReader("aaa.txt"); //创建输入流对象,关联aaa.txt
int ch;
while((ch = fr.read()) != -1) { //将读到的字符赋值给ch
System.out.println((char)ch); //将读到的字符强转后打印
}
fr.close(); //关流
2)FileWriter类的write()方法可以自动把字符转为字节写出,具有2k缓冲区域
FileWriter fw = new FileWriter("aaa.txt");
fw.write("aaa");
fw.close();
3)字符流的拷贝
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");
int ch;
while((ch = fr.read()) != -1) {
fw.write(ch);
}
fr.close();
fw.close();
4)IO流拷贝
字符流的拷贝工作需要将字节转换成字符,再将字符转换成字节才可完成,而字节流的拷贝只是字节的搬运,没有字节转换的时间,拷贝效率比较高,而且对于非纯文本文件,由于字符流会进行字节转换,在转换过程中可能找不到对应字符,就用?代替,这样写出时就会造成乱码,所以对于文件的拷贝使用字节流,只读或只写纯文本文件时使用字符流。
3. 字符流小数组拷贝,由于无法确定文件中字符的个数所以字符流没有available()方法
FileReader fr = new FileReader("aaa.txt"); //创建字符输入流,关联aaa.txt
FileWriter fw = new FileWriter("bbb.txt"); //创建字符输出流,关联bbb.txt
int len;
char[] arr = new char[1024*8]; //创建字符数组
while((len = fr.read(arr)) != -1) { //将数据读到字符数组中
fw.write(arr, 0, len); //从字符数组将数据写到文件上
}
fr.close(); //关流释放资源
fw.close();
4. BufferedReader的read()方法读取字符时会一次读取若干字符到缓冲区, 然后逐个返回给程序, 降低读取文件的次数, 提高效率。BufferedWriter的write()方法写出字符时会先写到缓冲区, 缓冲区写满时才会写到文件, 降低写文件的次数, 提高效率。缓冲区大小为8192。
示例程序
BufferedReader br = new BufferedReader(new FileReader("aaa.txt")); //创建字符输入流对象,关联aaa.txt
BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt")); //创建字符输出流对象,关联bbb.txt
int ch;
while((ch = br.read()) != -1) {
//read一次,会先将缓冲区读满,从缓冲去中一个一个的返给临时变量ch
bw.write(ch);
//write一次,是将数据装到字符数组,装满后再一起写出去
}
br.close(); //关流
bw.close();
5. 字符流的方法
1)BufferedReader的readLine()方法可以读取一行字符(不包含换行符号)。readLine()方法读取一个文本行,通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行。返回类型为字符串,不包含任何行终止符,如果已到达流末尾,则返回 null。
BufferedWriter的newLine()可以输出一个跨平台的换行符号"\r\n"。而"\r\n"只支持windows系统。
示例程序
BufferedReader br = new BufferedReader(new FileReader("aaa.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt"));
String line;
while((line = br.readLine()) != null) {
bw.write(line);
bw.newLine(); //跨平台的
}
br.close();
bw.close();
2) LineNumberReader是BufferedReader的子类, 具有相同的功能, 并且可以统计行号,调用getLineNumber()方法可以获取当前行号,调用setLineNumber()方法可以设置当前行号。从其源码中可以找到LineNumber成员变量,初始值为1,每调用一次readLine(),其值就会加1。
*
LineNumberReader lnr = new LineNumberReader(new FileReader("aaa.txt"));
String line;
lnr.setLineNumber(100); //设置行号
while((line = lnr.readLine()) != null) {
System.out.println(lnr.getLineNumber() + ":" + line);//获取行号
}
lnr.close();
6. 使用指定码表读写字符
FileReader是使用默认码表读取文件, 如果需要使用指定码表读取, 那么可以使用InputStreamReader(字节流,编码表);FileWriter是使用默认码表写出文件, 如果需要使用指定码表写出, 那么可以使用OutputStreamWriter(字节流,编码表)。GBK码表一个中文是两个字符,UTF-8码表一个中文是三个字符。
示例程序
BufferedReader br = newBufferedReader(new InputStreamReader(new FileInputStream("UTF-8.txt"), "UTF-8"));
//高效的用指定的编码表读
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("GBK.txt"), "GBK"));
//高效的用指定的编码表写
int ch;
while((ch = br.read()) != -1) {
bw.write(ch);
}
br.close();
bw.close();
后继
|
|