字符流与字节流
字节流直接操作文件,写入文件:最基本的两个类是InputStream、OutputStream;都是抽象类,不能用new;
字符流需要先放入缓存后,在从缓存写入文件:最基本的两个类是Writer、Reader;都是抽象类;
字节流主要处理二进制数据;
InputStream中有read()方法,字节流在默认情况下是不支持缓存的,这意味着每调用一次read方法都会请求操作系统来读取一个字节,这往往会伴随着一次磁盘IO,因此效率会比较低。
要使用内存缓冲区以提高读取的效率,我们应该使用BufferedInputStream;
字符流处理的最基本的单元是Unicode码元(大小2字节),通常用来处理文本数据(Java中的String类型默认就把字符以Unicode规则编码而后存储在内存中。)
然而与存储在内存中不同,存储在磁盘上的数据通常有着各种各样的编码方式。使用不同的编码方式,相同的字符会有不同的二进制表示。实际上字符流是这样工作的:
输出字符流:把要写入文件的字符序列(实际上是Unicode码元序列)转为指定编码方式下的字节序列,然后再写入到文件中;
输入字符流:把要读取的字节序列按指定编码方式解码为相应字符序列(实际上是Unicode码元序列从)从而可以存在内存中。
字符流与字节流的区别
- 复制文本文件,可以用字节流也可以用字符流;复制非文本文件,只可以用字节流;
- 经过以上的描述,我们可以知道字节流与字符流之间主要的区别体现在以下几个方面:
- ·字节流操作的基本单元为字节;字符流操作的基本单元为Unicode码元。
- ·字节流默认不使用缓冲区;字符流使用缓冲区。
- ·字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元;字符流通常处理文本数据,它支持写入及读取Unicode码元。
字节流 |
单个字符 |
数组 |
FileInputStream |
read() |
read(byte[] b) 或read(byte[]b,int off,int len) |
FileOutputStream |
write(int c) |
write(byte[]b,int off,int len) |
BufferedInputStream |
read() |
read(byte[] b) |
BufferedOutputStream |
write(int c) |
write(byte[]b,int off,int len) |
字符流 |
单个字符 |
数组 |
其他 |
FileReader |
read() |
read(char[] c)或 read(byte[]b,int off,int len) |
read(CharBuffer cb) |
FileWriter |
write(int c) |
write(char[] c)或 write(byte[]b,int off,int len) |
write(String s)或 write(String s,int off,int len) |
BufferedFileReader |
read() |
read(int c) |
readLine() |
BufferedFileWriter |
write(int c) |
write(char[]c,int off,int len) |
writeLine(String str) |
public class Main{ public static void main(String []args) throws IOException{ File infile=new File("1.txt"); File outfile=new File("2.txt"); File outfile2=new File("3.txt"); //////////////////////////////////////////// ///字节流 单个字节 FileInputStream fi=new FileInputStream(infile); FileOutputStream fo=new FileOutputStream(outfile); int c; while((c=fi.read())!=-1) {//读取单个字节,-1代表已达到流的末尾 fo.write(c); } fo.flush(); fi.close();fo.close(); /////////////////////////////////////////////////////////// ///字节流 字节数组 FileInputStream fi2=new FileInputStream(infile); FileOutputStream fo2=new FileOutputStream(outfile2); //缓存,必须从FileInputStream读取,而不是文件 BufferedInputStream bfi2=new BufferedInputStream(fi2); BufferedOutputStream bfo2=new BufferedOutputStream(fo2); int len; byte[] arr=new byte[10]; while((len=bfi2.read(arr))!=-1) {//每次以arr的大小来读取数据 bfo2.write(arr, 0, len); System.out.println(len);///10 10 6 } bfo2.flush(); fi2.close(); bfi2.close(); fo2.close(); bfo2.close(); /////////////////////////////////////////////////////////// ///字符流 以行的形式读入 FileReader fr=new FileReader(infile); FileWriter fw=new FileWriter(outfile); BufferedReader br = new BufferedReader(fr); BufferedWriter bw = new BufferedWriter(fw); String s; while((s = br.readLine()) != null){//字符流 fw.write(s);///write(String) System.out.println(s); bw.newLine();bw.flush();///没有此行的两个函数,就会全部写在一行,不会分行 } bw.flush();fr.close();fw.close(); br.close();bw.close(); } } |
注意:如果没有flush或close都不会看到结果