javaday23 字节流_字符流

字节流:

在前面的学习过程中,我们一直都是在操作文件或者文件夹,并没有给文件中写任何数据。现在我们就要开始给文件中写数据,或者读取文件中的数据。

字节输出流 OutputStream:

字节输出流可以操作任何文件,因为它是最小单位 字节来操作的。(一个字节等于8个二进制位)。

OutputStream此抽象类(它直接继承 java.lang.Object),是表示输出字节流的所有类的超类。操作的数据都是字节,它定义了输出字节流的基本共性功能方法。

抽象类 方法概述:

常用的方法是:

write 和  close 。分别用来想文件中写入。和 释放与流 相关的操作系统资源(因为真实的情况,写入到文件中,是程序调用操作系统来完成的,所以写入完毕之后要释放操作系统资源!)

字节输出流 FileOutputStream:

它继承OutputStream。作用是 写入到文件中。

IO这里的类名,命名很有特点,它的后半部分说明的是它继承的父类是谁,它的后半部分说明的是它自己的作用

对于FileOutputStream来说,它的构造函数中传入的参数是它要将数据存入的文件对象/或文件路径。如果文件不存在,就创建新文件,如果已经有了就直接覆盖掉了。

 1 package cn.zcb.demo02;
 2 
 3 import java.io.FileOutputStream;
 4 import java.io.IOException;
 5 
 6 public class Test{
 7     //FileOutputStream 类的使用
 8     public static void main(String[] args) throws IOException {
 9         FileOutputStream fostream = new FileOutputStream("d:\a.txt");
10         //使用fostream.write() 向文件中写 内容。
11         //write() 方法之 write(int a)// 此时是写入一个字节。
12         fostream.write(100);// 100 先作为字节。然后写入。
13 
14         fostream.close();//释放操作系统资源
15     }
16 }
View Code
 1 package cn.zcb.demo02;
 2 
 3 import java.io.FileOutputStream;
 4 import java.io.IOException;
 5 
 6 public class Test{
 7     //FileOutputStream 类的使用 
 8     public static void main(String[] args) throws IOException {
 9         FileOutputStream fostream = new FileOutputStream("d:\a.txt");
10         //使用fostream.write() 向文件中写 内容。
11         //write() 方法之 write(int a)// 此时是写入一个字节。
12         fostream.write(100);
13         // 100 变为一个字节: b 0011 1010  然后存入文件。 
14         //此时,如果我们打开文件查看,我们看不到二进制,因为在我们看到之前已经进行了转码了。
15         
16         
17         fostream.close();//释放操作系统资源  
18     }    
19 }
补充!

此时打开文件,会发现里面的是个字符 “d”,因为我们写的100 是一个字节写入的。

但是,我们用编辑器打开一个文件的时候,编辑器都会将里面的内容用编码表进行编码。

对于汉字,如果是GBK编码的话,一个汉字是两个字节。如果是UTF8的话一个汉字是3个字节!

 1 package cn.zcb.demo02;
 2 
 3 import java.io.FileOutputStream;
 4 import java.io.IOException;
 5 
 6 public class Test{
 7     //FileOutputStream 类的使用
 8     public static void main(String[] args) throws IOException {
 9         FileOutputStream fostream = new FileOutputStream("d:\a.txt");
10         fostream.write(49); //49 是 '1'的ASCII值
11         fostream.write(48);
12         fostream.write(48); 
13         
14         fostream.close();//释放操作系统资源
15     }
16 }
此时,打开文件,里面是“100”,三个字节。使用了.write() 三次,一次写入一个字节。
 1 package cn.zcb.demo02;
 2 
 3 import java.io.FileOutputStream;
 4 import java.io.IOException;
 5 
 6 public class Test{
 7     //FileOutputStream 类的使用
 8     public static void main(String[] args) throws IOException {
 9         FileOutputStream fostream = new FileOutputStream("d:\a.txt");
10         //1,写 一个字节。  write(int a);
11         fostream.write(49); //49 是 '1'的ASCII值
12         fostream.write(97); //97 是 'a' 的ASCII值
13 
14         //写入一个字节分隔
15         fostream.write('|');// '|' 先转为int 类型,然后int 转为一个字节,然后存入到文件中。
16 
17         //2,写 字节数组  write(byte [] )
18         byte [] arr = {65,66,67,68}; //'A' 'B' 'C' 'D'
19         fostream.write(arr);
20 
21 
22         fostream.write('|');
23         byte [] arr1 = {65,66,67,68}; //byte 的范围 【-128,127】
24         fostream.write(arr1);
25 
26         fostream.write('|');
27         byte [] arr2 = {-65,-66,-67,-68};
28         fostream.write(arr1,1,2);
29 
30         fostream.close();//释放操作系统资源
31     }
32 }
write() 方法的多种重载形式
 1 package cn.zcb.demo02;
 2 
 3 import java.io.FileOutputStream;
 4 import java.io.IOException;
 5 
 6 public class Test{
 7     //FileOutputStream 类的使用
 8     public static void main(String[] args) throws IOException {
 9 
10         FileOutputStream f = new FileOutputStream("d:\a.txt");
11 
12         //字节类型的取值为 【 -128  ,- 127】
13 
14         f.write("Hello World".getBytes());//写入文件的简便写法。
15 //        "Hello world" 先变为字节数组  {72 101 108 108 111 32 87 111 114 108 100 } 然后再写入文件。
16         f.write('|');
17 
18 
19         f.write("我爱你中国".getBytes());
20         //中文 “我爱你中国”  也是先变为 字节数组 如下:
21         //arr = { -26 -120 -111 -25 -120 -79 -28 -67 -96 -28 -72 -83 -27 -101 -67} //UTF8 三个字节一个汉字。
22 //        -26 -120 -111  的二进制 分别如下:1110 0110 1000 1000 1001 0001 于是可以推知 汉字"我"的三个字节为:1110 0110 1000 1000 1001 0001
23         
24 
25         /*
26         //字节类型 的范围   1000 0000(-128)  <-- 1111 1111(-1) <-- 0000 0000 -->   0111 1111(127) 注:这种表示都是补码。
27         //1111 1111
28         //0000 0001
29         //正数 的原码,反码,补码都是一样的。那么负数呢?
30         //负数的,要用正数的补码 取反,然后再加1得到负数的补码。计算机中用的    就只是补码。
31         // 1 2 4  8 16 32 64 128
32         byte a = -26;  //-26的 补码是:26补码: 0001 1010;  然后取反 1110 0101;然后加一 得到:1110 0110; 故-26补码为:1110 0110
33         byte b = -120; //同理 ,-120 的补码是: 1000 1000
34         byte c = -111; // -111 的补码是:      1001 0001
35 
36         /*输出 二进制代表的值
37         byte ret = (byte) 0b10010001;
38         System.out.println(ret);
39         */
40 
41         /*
42         * 如何 查看 我爱你中国   的字节数组表示:
43         byte[] ret =  "我爱你中国".getBytes();
44         for (int i = 0;i<ret.length;i++){
45             System.out.print(ret[i]+" ");
46         }
47         * */
48         //不管怎样,FileOutputStream 都是一次一个字节地  写入的。
49     }
50 
51 
52 
53 }
通过字符串.getBytes()方法,简化 字节数组方式写入的 工作。

.getBytes() 会返回一个 字节数组,我们直接将其写入即可。 

在文件的末尾 继续写:

它只需要在 FileOutputStream的构造方法中的第二个参数,传入true即可。它的那个参数append ,默认是false ,代表不append,如果传入的是true ,就是代表写入文件时不覆盖原文件。 

 1 package cn.zcb.demo02;
 2 
 3 import java.io.File;
 4 import java.io.FileOutputStream;
 5 import java.io.IOException;
 6 
 7 public class Test{
 8     //FileOutputStream 类的使用  字节流(以字节写入)
 9     public static void main(String[] args) throws IOException {
10         File file = new File("d:\a.txt");
11         FileOutputStream fd = new FileOutputStream(file,true); //true代表的意思是 在文件末尾添加内容。
12 
13         fd.write("hello".getBytes());
14         fd.write("我爱你中国".getBytes());
15 
16         fd.close();  //释放系统资源
17     }
18 }
View Code

在文件中 写入换行符:

 1 package cn.zcb.demo02;
 2 
 3 import java.io.File;
 4 import java.io.FileOutputStream;
 5 import java.io.IOException;
 6 
 7 public class Test{
 8     //FileOutputStream 类的使用  字节流(以字节写入)
 9     public static void main(String[] args) throws IOException {
10         File file = new File("d:\a.txt");
11         FileOutputStream fd = new FileOutputStream(file); //覆盖写
12         fd.write("Hello World
".getBytes()); //此时直接写 
 也是可以的。程序帮我们做了处理的!  
13         fd.write("我爱你中国".getBytes());
14 
15         fd.close();  //释放系统资源
16     }
17 }
View Code

IO流中的异常处理:

在FileOutputStream类 和 .write() 写入文件的时候,我们总是会遇到编译器 提示,可能会出现  找不到文件异常,和写入文件失败异常。

文件找不到的异常叫做:FileNotFoundException  

文件写入失败异常叫做:IOException

二者关系是 FileNotFoundException  --> IOException

我们不能总是将异常抛出到JVM中。这里我们就使用try -catch  -finally 来处理它。

package cn.zcb.demo02;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test{
    //FileOutputStream 类的使用  字节流(以字节写入)
    public static void main(String[] args){

        /*version 1
        try {
            FileOutputStream fd = new FileOutputStream("d:\a.txt");
            fd.write("hello world".getBytes());
        }catch (FileNotFoundException e){
            System.out.println(e);
        }catch (IOException e){
            System.out.println(e);
        }finally {
            fd.close();//这里会报错  ,因为这里访问不到fd ,应该在try 作用域外面声明fd变量,然后再try 中给其赋值,这样在 finally中也就可以使用使用了。
        }
         */

        //代码如下:事实有问题
        /*version 2
        FileOutputStream fd;
        try {
            fd = new FileOutputStream("d:\a.txt");
            fd.write("hello world".getBytes());
        }catch (FileNotFoundException e){
            System.out.println(e);
        }catch (IOException e){
            System.out.println(e);
        }finally {
            fd.close(); //报错 fd可能 未被初始化。
         }

         */

        /*version 3 解决可能为被初始化问题之后,又出错。
        FileOutputStream fd = null;
        try {
            fd = new FileOutputStream("d:\a.txt");
            fd.write("hello world".getBytes());
        }catch (FileNotFoundException e){
            System.out.println(e);
        }catch (IOException e){
            System.out.println(e);
        }finally {
            fd.close(); //报错 可能会产生 IOException 异常。
        }
         */

        //version 最终版本。
        FileOutputStream fd = null;
        try {
            fd = new FileOutputStream("d:\a.txt");
            fd.write("hello world".getBytes());
        }catch (FileNotFoundException e){
            System.out.println(e);
            throw new RuntimeException("文件写入失败,请重试!!!");  //这种场景是 电脑上差一个u盘,然后程序向u盘写数据,写着写着,我们如果突然拔掉u盘,那么此时的程序是无法继续的。只能重试。告知用户执行失败。这就是 很多硬件的问题,软件(程序)是无法处理的。
        }catch (IOException e){
            System.out.println(e);
        }finally {
            try {
                fd.close(); //在这里处理异常。
            }catch (IOException e){
                System.out.println(e);
                throw new RuntimeException("关闭资源失败。。。"); //也不是没可能,当系统资源崩溃的时候,我们就不能释放系统资源了。
            }
        }

    }
}
View Code

 还有 在fd.close() 之前最好要 判断是否为null !

字节输入流 InputStream:

读取数据到程序中。 

字节输入流 FileInputStream:

它的构造方法:

fd.read()方法:

 1 package cn.zcb.demo02;
 2 import java.io.FileInputStream;
 3 import java.io.IOException;
 4 
 5 public class Test{
 6     //FileInputStream 类的使用
 7     public static void main(String[] args) throws IOException {
 8         //1
 9         FileInputStream fd = new FileInputStream("d:\a.txt"); //a.txt中存储的内容是 abc
10 
11         int i= fd.read(); //fd.read() 时,每次都是返回一次字节。
12         System.out.println(i);
13         i = fd.read();
14         System.out.println(i);
15         i = fd.read();
16         System.out.println(i);
17 
18         i = fd.read();  //此时已经没有数据了。返回-1
19         System.out.println(i);
20         i= fd.read();
21         System.out.println(i); //还读,还是-1
22         
23 
24 
25 
26         //3释放资源
27         fd.close();
28     }
29 }
FileInputStream类的 read() 方法的特点。
 1 package cn.zcb.demo02;
 2 import java.io.FileInputStream;
 3 import java.io.IOException;
 4 
 5 public class Test{
 6     //FileInputStream 类的使用
 7     public static void main(String[] args) throws IOException {
 8         //1
 9         FileInputStream fd = new FileInputStream("d:\a.txt"); //a.txt中存储的内容是 abc
10 
11         int temp= 0;
12         //使用循环读取
13         while ((temp = fd.read()) != -1){
14             System.out.print((char)temp);
15         }
16         //3释放资源
17         fd.close();
18     }
19 }
上面的程序只是为了看到 读取到的最后时 的 -1 一般正常读取时候要用循环度。

fd.read(byte [] )方法:

上面两个问题很重要,

1,数组的作用?

2,函数返回的int 是什么?

答:

1,数组是做为一个传入参数的,读到的字节会放到里面。它起到了缓冲的作用。如果数组大小设置过小,要读好多次,才能全部读入。

2,int 是读取到了多少个有效的字节数。 如果一次read() 的时候,一个字节都没读取到,就返回 -1.即完成了文件的读取。

 1 package cn.zcb.demo02;
 2 import java.io.FileInputStream;
 3 import java.io.IOException;
 4 
 5 public class Test{
 6     //FileInputStream 类的使用
 7     public static void main(String[] args) throws IOException {
 8         //1
 9         FileInputStream fd = new FileInputStream("d:\a.txt"); //a.txt中存储的内容abcde
10 
11         byte [] arr =new byte[2];
12         int ret = fd.read(arr);
13 
14         //输出数组中的内容 。。。。
15         System.out.println(new String(arr)); //ab
16         /* 如下的遍历,也可以看到字节数组中的内容
17         for (int i =0;i<arr.length;i++){
18             System.out.print(arr[i]);  //9798
19         }
20          */
21         //查看函数的返回值  为2 代表读出了几个字节。
22         System.out.println(ret);
23 
24         //继续读取
25         ret = fd.read(arr);
26         System.out.println(new String(arr)); //cd
27         System.out.println(ret);  //2
28 
29         //继续读取
30         ret = fd.read(arr);
31         System.out.println(new String(arr)); //ed  之所以出现ed是因为arr数组没有清空,上次的d没有清楚掉
32         System.out.println(ret); //1  //此时,虽然数组没有读满,但是起码还是读了一个,所以不返回-1 
33 
34         //如果继续打印
35         ret = fd.read(arr);
36         System.out.println(new String(arr)); //ed ,仍然是上次的结果。 
37         System.out.println(ret); //-1  ,此时一个都没读取到,返回 -1
38 
39         //3释放资源
40         fd.close();
41     }
42 }
相关代码
 1 package cn.zcb.demo02;
 2 import java.io.FileInputStream;
 3 import java.io.IOException;
 4 import java.util.Arrays;
 5 
 6 public class Test{
 7     //FileInputStream 类的使用
 8     public static void main(String[] args) throws IOException {
 9         //1
10         FileInputStream fd = new FileInputStream("d:\a.txt"); //a.txt中存储的内容abcde
11 
12         byte [] arr =new byte[2]; //1,用来存放读来的数据  传入参数!!!
13         int ret = 0;  //2, 函数的返回值 ,用于获取读了多少个字节 和  是否读取完毕。传出参数。
14         while ((ret = fd.read(arr)) != -1 ){ //此时就没有读完。。。
15             System.out.println(new String(arr));
16             //清空 arr,以免污染下次读取。
17             Arrays.fill(arr,(byte)0); //类似于 C语言中的 memset ,此时就不会出现污染问题了!
18         }
19         //3释放资源
20         fd.close();
21     }
22 }
正常读取文件时使用循环读取。

不过,我们要注意,一般存放我们读取出来的数组,我们一般设置为1024 个字节。就是一次最多可以放1024个字节。

而且要注意 读取之后要使用Arrays.fill(arr,byte(0)); 将其置空。  

文件复制原理:

 1 package cn.zcb.demo02;
 2 
 3 
 4 import java.io.FileInputStream;
 5 import java.io.FileNotFoundException;
 6 import java.io.FileOutputStream;
 7 import java.io.IOException;
 8 
 9 public class Test{
10     public static void main(String[] args) {
11         //一个字节一个字节的读。
12         try {
13             FileInputStream fdIn = new FileInputStream("d:\a.txt"); //src
14             FileOutputStream fdOut = new FileOutputStream("e:\a.txt");//dest
15 
16             int ret = 0;
17             while ((ret = fdIn.read()) != -1){
18                 fdOut.write(ret);
19             }
20         }catch (FileNotFoundException e){
21             e.printStackTrace(); //此时文件为找到。
22         }catch(IOException e){
23             e.printStackTrace();
24         }finally {
25             
26 
27         }
28 
29     }
30 }
version 01
 1 package cn.zcb.demo02;
 2 
 3 
 4 import com.sun.source.doctree.ThrowsTree;
 5 
 6 import java.io.FileInputStream;
 7 import java.io.FileNotFoundException;
 8 import java.io.FileOutputStream;
 9 import java.io.IOException;
10 import java.util.PropertyResourceBundle;
11 
12 public class Test{
13     public static void main(String[] args) {
14         //一个字节一个字节的读。
15         FileInputStream fdIn = null;
16         FileOutputStream fdOut = null;
17         try {
18             fdIn = new FileInputStream("d:\a.txt"); //src
19             fdOut = new FileOutputStream("e:\a.txt");//dest
20 
21             int ret = 0;
22             while ((ret = fdIn.read()) != -1){
23                 fdOut.write(ret);
24             }
25         }catch (FileNotFoundException e){
26             e.printStackTrace(); //此时文件未找到。
27         }catch(IOException e){
28             e.printStackTrace(); //此时文件 发生异常。
29         }finally {
30             try {
31                 if(fdOut != null)   //先开后关!!!
32                     fdOut.close();
33             }catch (IOException e){
34                 e.printStackTrace();
35             }finally {
36                 try{
37                     if(fdIn != null)
38                         fdIn.close();
39                 }catch (IOException e){
40                     e.printStackTrace();
41                 }
42             }
43         }
44     }
45 }
View Code

但是,上面的代码是很低效的,因为它是读入一个字节,然后又读出到文件中。

下面用字节数组做缓冲,来提高效率!!!

 1 package cn.zcb.demo02;
 2 
 3 import java.io.FileInputStream;
 4 import java.io.FileNotFoundException;
 5 import java.io.FileOutputStream;
 6 import java.io.IOException;
 7 import java.util.Arrays;
 8 
 9 public class Test{
10     public static void main(String[] args) {
11         //一个字节一个字节的读。
12         FileInputStream fdIn = null;
13         FileOutputStream fdOut = null;
14         try {
15             fdIn = new FileInputStream("d:\shipin.mp4"); //src
16             fdOut = new FileOutputStream("e:\shipin.mp4");//dest
17 
18             int ret = 0;
19             byte [] arr = new byte[1024]; //一次读取 1M
20             while ((ret = fdIn.read(arr)) != -1){
21                 fdOut.write(arr);
22                 //arr 置空
23                 Arrays.fill(arr,(byte)0);
24             }
25         }catch (FileNotFoundException e){
26             e.printStackTrace(); //此时文件未找到。
27         }catch(IOException e){
28             e.printStackTrace(); //此时文件 发生异常。
29         }finally {
30             try {
31                 if(fdOut != null)   //先开后关!!!
32                     fdOut.close();
33             }catch (IOException e){
34                 e.printStackTrace();
35             }finally {
36                 try{
37                     if(fdIn != null)
38                         fdIn.close();
39                 }catch (IOException e){
40                     e.printStackTrace();
41                 }
42             }
43         }
44     }
45 }
一次读1024(1K),一次写1K ,效率得到很大提高

1M = 1024K = 1024*1024字节。

对于10M的文件,

如果用一次读一字节,写一字节。那么程序循环要执行 10*1024*1024 次。

而如果使用一次读1024字节,写1024字节。那么程序循环只需要执行10*1024次!

编码表:

为了操作字符流,我们需要知道编码表。

我们知道计算机底层数据存储的都是二进制数据,而我们生活中的各种各样的数据,如何才能和计算机中存储的二进制数据对应起来呢?

这时老美他们就把每一个字符和一个整数对应起来,就形成了一张编码表,老美他们的编码表就是ASCII表。其中就是各种英文字符对应的编码。

编码表:其实就是生活中字符和计算机二进制的对应关系表。

1、ascii: 一个字节中的7位就可以表示。对应的字节都是正数。0-xxxxxxx

2、iso-8859-1:拉丁码表 latin,用了一个字节用的8位。1-xxxxxxx  负数。

3、GB2312:简体中文码表。包含6000-7000中文和符号。用两个字节表示。两个字节第一个字节是负数,第二个字节可能是正数

       GBK:目前最常用的中文码表,2万的中文和符号。用两个字节表示,两个字节第一个字节是负数,第二个字节可能是正数

              GB18030:最新的中文码表,目前还没有正式使用。

4,unicode:国际标准码表:无论是什么文字,都用两个字节存储。

l  Java中的char类型用的就是这个码表。char c = 'a';占两个字节。

l  Java中的字符串是按照系统默认码表来解析的。简体中文版 字符串默认的码表是GBK。

5、UTF-8:基于unicode,不定长字节。一个字节就可以存储数据,不要用两个字节存储,而且这个码表更加的标准化,在每一个字节头加入了编码信息(后期到api中查找)。

能识别中文的码表:GBK、UTF-8;正因为识别中文码表不唯一,涉及到了编码解码问题。

对于我们开发而言;常见的编码 GBK  UTF-8  ISO-8859-1

文字--->(数字) :编码。 “abc”.getBytes()  byte[]

(数字)--->文字  : 解码。 byte[] b={97,98,99}  new String(b)

流对象的另一种---字符流:

字符流只能写字符。所以它用于文本处理!

而上面的字节流则可以处理图片,视频啊,等等。

字符输出流 Writer:

字符输出流 Writer学习 ---FileWriter(Writer超类的已知子类):

 1 package cn.zcb.demo02;
 2 
 3 import java.io.FileWriter;
 4 import java.io.IOException;
 5 
 6 public class Test{
 7     public static void main(String[] args) throws IOException {
 8         //FileWriter 学习
 9         FileWriter fd = new FileWriter("d:\a.txt");
10 
11         //1, 写1个字符。
12         /*
13         fd.write(100);//'a'
14         fd.flush(); //不然的话,看不见。
15          */
16 
17         /*
18         //2, 写1个字符数组
19         char [] arr = {'a','b','c','d','e'};
20         fd.write(arr);
21         fd.flush();
22 
23         //2,写1个字符数组的部分
24         fd.write(arr,1,3); //从偏移量0 开始写入3个字符。
25         fd.flush();
26         */
27 
28         //3,写字符串
29         fd.write("tom hello world");
30         fd.flush();
31 
32         fd.close(); //.close()暗含 .flush()
33     }
34 }
View Code

字符输入流:

字符输入流 Reader学习 ---FileReader(Reader超类的已知子类):

 1 package cn.zcb.demo02;
 2 
 3 import java.io.FileReader;
 4 import java.io.IOException;
 5 
 6 public class Test{
 7     public static void main(String[] args) throws IOException {
 8         //FileReader 学习
 9         FileReader fd = new FileReader("d:\a.txt"); //读中文也是可以的。
10         
11         //1,一次读入一个字符
12         /**/
13         int ret = 0;
14         while ((ret = fd.read()) != -1){
15             System.out.print((char)ret);
16         }
17 
18         fd.close();
19     }
20 }
字符输入流。

如果想要读入一个中文文件,也想看到结果的,建议不要使用字节流,使用字符流。

Reader是可以处理中文的。

 1 package cn.zcb.demo02;
 2 
 3 import java.io.FileReader;
 4 import java.io.IOException;
 5 import java.util.Arrays;
 6 
 7 public class Test{
 8     public static void main(String[] args) throws IOException {
 9         //FileReader 学习
10         FileReader fd = new FileReader("d:\a.txt"); //读中文也是可以的。
11 
12         //1,一次读入一个字符
13         /*
14         int ret = 0;
15         while ((ret = fd.read()) != -1){
16             System.out.print((char)ret);
17         }
18         */
19 
20         //2,一次读入一个字符数组
21         char [] arr = new char[1024];
22         int ret = 0;
23         while ((ret = fd.read(arr)) != -1){
24             System.out.println(new String(arr));
25             //置空 arr
26             Arrays.fill(arr,'0');
27         }
28         
29 
30 
31 
32         fd.close();
33     }
34 }
一次读入一个数组,效率高!

flush()  和 close() 的区别:

flush():将流中的缓冲区缓冲的数据刷新到目的地中,刷新后,流还可以继续使用。而且它只有写文件(字符流,字节流)时候使用。  

close():关闭资源,但在关闭前会将缓冲区中的数据先刷新到目的地,否则丢失数据,然后在关闭流。流不可以使用。如果写入数据多,一定要一边写一边刷新,最后一次可以不刷新,由close完成刷新并关闭。

字符流复制 文本文件:

注:字符流只能处理字符。

 1 package cn.zcb.demo02;
 2 
 3 
 4 import java.io.*;
 5 import java.util.Arrays;
 6 
 7 public class Test{
 8     public static void main(String[] args) throws IOException {
 9         // 注,它只能读 字符。  只能处理文本!!!
10         FileWriter fdWr = null;
11         FileReader fdRd = null;
12         try {
13             fdRd = new FileReader("d:\a.txt");
14             fdWr= new FileWriter("e:\dest.txt");
15 
16             int ret = 0;
17             char [] arr = new char[1024];           //一次读取 2K 一个字符2个字节。
18             while ((ret = fdRd.read(arr)) != -1){
19                 fdWr.write(arr);
20                 //arr 置空
21                 Arrays.fill(arr,'0');
22             }
23         }catch (FileNotFoundException e){
24             e.printStackTrace(); //此时文件未找到。
25         }catch(IOException e){
26             e.printStackTrace(); //此时文件 发生异常。
27         }finally {
28             try {
29                 if(fdWr != null)   //先开后关!!!
30                     fdWr.close();
31             }catch (IOException e){
32                 e.printStackTrace();
33             }finally {
34                 try{
35                     if(fdRd != null)
36                         fdRd.close();
37                 }catch (IOException e){
38                     e.printStackTrace();
39                 }
40             }
41         }
42     }
43 }
View Code
原文地址:https://www.cnblogs.com/zach0812/p/11937761.html