字符流(一次读取一个字符)
概述:字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串。字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的。字符流操作的是缓冲区(当我们对文件进行读写操作时如果不调用close() 或 flush()方法时不能看到数据的变化)。
实现字符流与字节流的转换:StreamDecoder
字符流复制文件
字符流复制文件的时候要注意在结束的时候要关闭缓冲区,字符流的write方法是利用一个char数组来实现的。
public class Test3 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader(new File("F:\\java工具\\jdk api 1.8_google.CHM"));
FileWriter fw = new FileWriter(new File("jdk api 1.8_google.CHM"));
int flag;
while ((flag = fr.read()) != -1){
fw.write(flag);
}
fr.close();
//字符流的内容实在缓冲区中,所以复制的时候要关闭
fw.close();
}
}
字符流不推荐使用复制纯文本文件
字符流比字节流多出了字节与字符的转换,但是字节流没有转换。相比来说,字节流更加适合文件的传输
字节流适合与读取有字符的文件。
字符流为什么不能使用在非纯文本的拷贝?
字符流:通过编码表将字节转换为字符(但是有些字符在码表中没有对应的编码),文件就会被损坏。 所以字符流不适合存储为纯文本
字符数组的拷贝
通过自定义字符数组来进行纯文本的拷贝
/**
* 字符流通过自定义字符数组进行拷贝
* @author kiosk
*/
public class Test4 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader(new File("content.txt"));
FileWriter fw = new FileWriter(new File("hello.txt"));
char[] chars = new char[1024];
int len;
while ((len = fr.read(chars)) != -1){
fw.write(chars);
}
fr.close();
fw.close();
}
}
缓冲字符流
默认的数组的大小为8092也就是16k
/**
* 缓冲字符流
* @author kiosk
*/
public class Test5 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("content.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("hello.txt"));
int flag;
while ((flag = br.read()) != -1){
bw.write(flag);
}
br.close();
bw.close();
}
}
按照行进行读取
/**
* 整行读取文件的内容(缓冲流)
* @author kiosk
*/
public class Test6 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("content.txt"));
String content;
//按照行进行读取,如果没有读取到的话,就返回的值为null
while ((content = br.readLine()) != null){
System.out.println(content);
}
br.close();
}
}
如果缓冲字符流读取的时候是按照行进行读取的,但是写的时候就不会进行换行了。如果想要换行,就要执行newLine()的方法
public class Test6 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("content.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("content2.txt"));
String content;
//按照行进行读取,如果没有读取到的话,就返回的值为null
while ((content = br.readLine()) != null){
bw.write(content);
//进行写的时候换一行
bw.newLine();
}
br.close();
bw.close();
}
}
newLine()方法与write("\r\n")的区别
newLine():跨平台的
write("\r\n"):在windows下与在Linux和mac下的换行符是不一样的。
将一个文本从后往前反转进行反转
代码如下:
/**
* 将一个文本的内容进行反转
* 晚开早关
* @author kiosk
*/
public class Test {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("content.txt"));
ArrayList<String> list = new ArrayList<String>();
String flag;
while ((flag = br.readLine()) != null){
list.add(flag);
}
br.close();
BufferedWriter bw = new BufferedWriter(new FileWriter("content.txt"));
for (int i = list.size() - 1; i >= 0 ; i--) {
bw.write(list.get(i));
bw.newLine();
}
bw.close();
}
}
LineNumberReader
可以给内容加上行号:每readLine一次就给行号加个1。
/**
* LineNumberReader
* @author kiosk
*/
public class Test2 {
public static void main(String[] args) throws IOException {
LineNumberReader reader = new LineNumberReader(new FileReader("content.txt"));
String line;
reader.setLineNumber(100);
while ((line = reader.readLine()) != null){
System.out.println(reader.getLineNumber() + ":" +line);
}
reader.close();
}
}