字符流
字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串。
我们已知道字节流处理单元为1个字节,操作字节和字节数组。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而形成的,所以它对多国语言支持性比较好!如果是视频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点。
所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。在读取文件(特别是文本文件)时,也是一个字节一个字节地读取以形成字节序列.
1.字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串;
2. 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。
继承关系
FileReader–>FileInputStream–>Reader
FileReader只能用于从文件中读取字符数据
FileWriter–>FileOutputStream–>Writer
FileWriter用于向文件中写字符
举个例子
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class lianxiIO {
public static void main(String[] args){
String str = "白日依山尽\n";
char[] ch = str.toCharArray();
FileWriter fw = null;
FileReader fr = null;
try {
fw = new FileWriter("登鹤雀楼.txt"); //注意:这是相对路径,在所创建的java项目里
fw.write(ch);
fw.write("黄河入海流\n");
fw.write("欲穷千里目\n");
fw.write("更上一层楼\n");
fw.close();
} catch (IOException e) {
System.err.println("流的创建、写和关闭都可能产生IOException异常。");
System.exit(-1);
}
try {
fr = new FileReader("登鹤雀楼.txt");
int i;
while ((i = fr.read()) != -1) {
System.out.print((char) i);
}
System.out.println();
fr.close();
} catch (FileNotFoundException e) {
System.err.println("文件未找到!");
System.exit(-2);
} catch (IOException e) {
System.err.println("读和关闭都可能产生IOException异常。");
System.exit(-3);
}
}
}
结果:
白日依山尽
黄河入海流
欲穷千里目
更上一层楼
一.字节流在操作时不会用到缓冲区(内存),是直接对文件本身进行操作的。而字符流在操作时使用了缓冲区,通过缓冲区再操作文件。
二.在硬盘上的所有文件都是以字节形式存在的(图片,声音,视频),而字符值在内存中才会形成。
三.字符流其实是通过转换流变化为字节流再进行IO操作
转换流
在进行字符流到文件流的转换Java提供了两个转换流:InputStreamReader和OutputStreamWriter。
①InputStreamReader类是从字节输入流获得数据,然后转换为字符数据交给程序使用。
OutputStreamWrite类是将程序输出的字符数据,先转换为字节数据后,再写到输出流中。
②InputStreamReader类是Reader类的直接子类。其构造方法的参数中必须指定一个InputStream字节输入流作为数据源,除此之外,还必须有相应的字符编码规范,以便将指定的字符编码转换为Unicode字符编码。
OutputStreamWriter类是Writer类的直接子类。同样,其构造方法的参数中也必须指定一个OutputStream字节输出流(作为数据目的地)和字符编码规范。
举个例子
public static void main(String[] args) throws IOException {
InputStreamReader ir = new InputStreamReader(System.in);
OutputStream fileOut = null;
int i;
OutputStreamWriter ow = null;
try {
fileOut = new FileOutputStream("encode.txt");
ow = new OutputStreamWriter(fileOut, "UTF8");
//ow = new OutputStreamWriter(new FileOutputStream("encoding.txt"),"UTF8");
System.out.println("写入文件的编码是:" + ow.getEncoding());//获取文件编码格式getEncoding()
System.out.print("请输入:");
while ((i = ir.read()) != '#') {
ow.write(i);
}
} catch (FileNotFoundException e) {
System.err.println("发生了FileNotFoundException异常。");
} catch (UnsupportedEncodingException e) {
System.err.println("发生了UnsupportedEncodingException异常。");
} finally {
ow.close();
fileOut.close();
}
InputStream fileIn = null;
InputStreamReader irFile = null;
try {
fileIn = new FileInputStream("encode.txt");
irFile = new InputStreamReader(fileIn, "UTF8");
System.out.println("从文件读入的编码是:" + irFile.getEncoding());
System.out.print("从文件读入的是:");
while ((i = irFile.read()) != -1) {
System.out.print((char) i);
}
} catch (FileNotFoundException e) {
System.err.println("发生了 FileNotFoundException异常。");
} catch (UnsupportedEncodingException e) {
System.err.println("发生了 UnsupportedEncodingException异常。");
} finally {
irFile.close();
fileIn.close();
}
}
}
写入文件的编码是:UTF8
请输入:克拉拉#
从文件读入的编码是:UTF8
从文件读入的是:克拉拉
在FileOutputStream(“encoding.txt”,true) 添加 true,则将字节写入文件末尾处,而不是写入文件开始处
UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。
缓冲流
为了提高数据的传输效率,特意引入缓冲流(Buffered Stream)的概念,为每一个流配置一个缓冲(Buffered),缓冲区就是存放传输数据的一块内存,向缓冲流中写数据时,系统先将数据发送到缓冲区,不是直接发送给外设,缓冲区会自动记录数据,当缓冲区的数据满了的时候,才将数据全部发送给外设,当从缓冲流中读数据的时候,系统实际是从缓冲区中读取数据,缓冲区为空的时候,系统就会从外部的相关设备自动读取数据,填满缓冲区。
1、BufferedReader类
2、BufferedWriter类
FileReader类和FileWriter类以字符为单位进行数据读写操作,数据的传输效率很低。Java提供BufferedReader和BufferedWriter类以缓冲流的方式进行数据读写操作,这两个流自带缓冲区。
举个例子:从键盘输入一首诗,以输入的格式保存在文件中,再显示在控制台
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入唐诗,每输入一行按回车键,直接按回车键结束:");
try{
int count=0;
FileWriter fw = new FileWriter("诗.txt");
BufferedWriter bw = new BufferedWriter(fw); //创建缓冲字符输出流对象
String line = null;
while((line=in.readLine())!= null){
if(line.length()== 0)break;
count++;
bw.write(count+")"+line+"\r\n"); //"\r\n"表示在文件中换行
}
bw.close();
in.close();
}catch(IOException e){
System.err.println(e.toString());
}
}
}
从文件读取这样写
File file = new File("诗.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
while((line = br.readLine())!=null){
System.out.println(line);
}
这样也可以
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("诗.txt")));