Java--FileReader/FileWriter

FileReader

字符输入流+访问文件==FileReader

当我们要对文件进行读入操作时,我们可以使用FileReader进行操作。
具体的操作的步骤用代码来一步步介绍:

为了完成操作,我们要事先再相对路径创建一个txt文件(我创建了一个hello.txt)
hello.txt内容是:HelloWorld123

           1,File file=new File("hello.txt");
           2,FileReader fr = new FileReader(file);
           3int data;
           	  while((data=fr.read())!=-1){
                System.out.print((char)data);
              }
           4,fr.close();

上面的编号是大致的步骤:

我们可以将其归纳为:
1,实例化File对象,指明要操作的文件
2,提供具体的流
3,数据的读入
4,流的关闭

接下来来看完整的代码:

  public void textFileReader()  {

        FileReader fr= null;

        try {
            //1,实例话File对象,指明要操作的文件
            File file=new File("hello.txt");
            //2,提供具体的流
            fr = new FileReader(file);
            //3,数据的读入
            //read():返回读入的一个字符。如果达到文件末尾,返回-1
            int data;
            while((data=fr.read())!=-1){
                System.out.print((char)data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4,流的关闭操作
            try {
                if (fr != null)
                    fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

上面代码有写要注意的点:

1,写代码时,会有多处会报异常,当我们写到一定步骤时,先把异常往上抛(等等讲原因)。

2,第三步骤:我们要知道,当我们文件读入到文件末尾时,会返回-1;while括里的意思是:我们先将读到的信息赋值给data(注意是int型的),之后判断是否到达文件末尾(返回-1)。之后打印(将其转化为字符型)
(System.out.print():表示输出不换行。若我们使用的时println,将每一行打印一个字符)

3,记住:要关闭流(java对物理的垃圾不会自回收,比如:socket)

4,把具体步骤写完后,因为我们之前是把异常往上抛了,现在要将throws改为try-catch-finally。不能使用throws,如果我们使用的是throws,比如当我们第三个步骤出现异常,下面的代码就不会运行了,我们就少了关闭流的操作,会导致资源的浪费。(前面将异常往上抛是因为:写的时候会出现多处异常,为了方便)
(将整个代码块try的快捷键:Ctrl+alt+t)
5,finally:if语句:如果步骤二(一)就报异常,所以就不会创建流对象,就不需要关闭流。


由上面的代码,我们可以总结几点:

1,read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1

2,异常处理:为了保证资源一定可以执行关闭操作。需要使用try-catch-finally来处理

3,读入的文件一定要存在,否者就会报异常(FileNotFoundException)


我们也可以发现一个问题,也就是我们打印是一个一个打印的,对此我们一般使用read的重载方法

代码如下:

    @Test
    public void textFileReader2() {
        FileReader fr= null;
        try {
            //1,File类的实例化
            File file=new File("hello.txt");
            //2,FileReader流的实例化
            fr = new FileReader(file);

            //3,读入的操作
            //read(char[] cbuf):返回每次读入cbuf数组中的字符个数,如果达到文件末尾,返回-1
            char[] cbuf=new char[5];

            /**
             * 重点难点:
             */
            int len;
            while((len=fr.read(cbuf))!=-1){
//                错误写法:
//                for(int i=0;i<cbuf.length;i++){
//                    System.out.print(cbuf[i]);
//                }
//                正确写法:
                for(int i=0;i<len;i++){
                    System.out.print(cbuf[i]);
                }

                String str=new String(cbuf,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4,资源的关闭
            try {
                if(fr!=null)
                    fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

相比第一个方法,只有在第三步骤上做了修改,其余步骤和第一个方法一致。

所以我们将第三步骤拿出来,单独分析:


            //3,读入的操作
            //read(char[] cbuf):返回每次读入cbuf数组中的字符个数,如果达到文件末尾,返回-1
            char[] cbuf=new char[5];

            /**
             * 重点难点:
             */
            int len;
            while((len=fr.read(cbuf))!=-1){
//                错误写法:
//                for(int i=0;i<cbuf.length;i++){
//                    System.out.print(cbuf[i]);
//                }
//                正确写法:
                for(int i=0;i<len;i++){
                    System.out.print(cbuf[i]);
                }

//                String str=new String(cbuf,0,len);
//              System.out.print(str);
            }

第三个步骤的意思是:创建一个char数组(相当于车的容量);用int来记录char数组的长度(相当于记录这辆车装了多少东西);
点进去read():
在这里插入图片描述
可以看出返回的是一个int类型,返回的是参数的长度。

错误写法:

                for(int i=0;i<cbuf.length;i++){
                    System.out.print(cbuf[i]);
                }

因为"cbuf.length"是“车的容量”,所以你打印的时:HelloWorld123ld。
只是把前三个字符覆盖了
同理,不能使用 String(char)这个方法,而是使用String(char,0,len)这个方法。


FileWriter

从内存中写出数据到硬盘中

说明:

(1)输出操作,对应File可以不存在

(2)File对应硬盘中的文件如果不存在,在输出过程中,会自动创建文件

  • 如果存在

1,如果流的使用构造器是:FileWriter(file,false)/FileWriter(file):对原有文件的覆盖

2,如果流的使用构造器是:FileWriter(file,true):不会对原有文件内容覆盖,而是在原有文件内容基础上追加内容

   @Test
    public void MyFileWriter1() {
        FileWriter fw= null;

        try {
            //File类实例化
            File file=new File("hello.txt");
            //提供具体的类
            fw = new FileWriter(file,true);
            //写出数据。如果对应的文件不存在,会自动创建文件
            fw.write("\nI love you");
            fw.write("在吗asd");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                if(fw!=null)
                    fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

过程大致和FileReader相同。


接下来我们要做一件事:将一个文件的内容复制到另一个文件里。

代码的解释就不写了

    @Test
    public void ReaderWriter() {
        String str=null;
        //File实例化
        File file=new File("hello.txt");
        File file1=new File("hello1.txt");
        //提供输入流
        FileReader fr= null;
        FileWriter fw= null;
        try {
            fr = new FileReader(file);
            fw = new FileWriter(file1);
            //读入操作,将数据从硬盘中读到内存中
            char[] cbuf=new char[5];//车的容量
            int len;
            while((len=fr.read(cbuf))!=-1){
              fw.write(cbuf,0,len);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                if(fr!=null)
                    fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(fw!=null)
                    fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

首先,我个人的想法原本是值操作一个文件,也就是将一个文件的内容提取出来,再复制回去。之后发现试了好多种方法都不行,文件内容会变成空。所以,最后还是用了两个文件进行操作。(如果有大佬看到的话,还望多多指点,谢谢)

发布了43 篇原创文章 · 获赞 0 · 访问量 956
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 岁月 设计师: pinMode

分享到微信朋友圈

×

扫一扫,手机浏览