学习记录之如何用Java读写文件(从零开始完整版)

249 阅读6分钟

注:仅分享自己的学习心得

我们从三个阶段学习读写文件,第一步创建文件路径,第二步创建txt文件并写入我们想要的内容,第三步从保存好的文件中读取内容。每一个部分都附上代码讲解,最后附上完整的可执行代码。

小白须知:所谓的文件读取,实质是将文件中的内容拿出来使用(比如存放到自定义的对象中调用)。相应的文件写入,即是将我们想要的内容写入到具体的文件中如txt文件。

一、创建文件目录以及txt文件

正式读取文件之前自然要先有地方保存文件啦,所以我们先讲解如何创建文件路径:

  • 首先定义一个字符串str,作为我们将要写入文件的内容使用。
  • 然后将我们自定义的文件路径使用File封装为一个对象,命名为destDir便于调用File的各种方法。
  • 此时需要调用exists()方法检查一下文件路径是否存在,不存在则调用mkdirs()方法进行逐级创建目录。

注:Java中的File类是用于表示文件和目录路径名的抽象表示。它提供了一组方法,可以用来操作文件系统中的文件和目录,包括创建、删除、重命名、检查属性等操作。

package com.lj.stu;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class Test {
    public static void main(String[] args) {
        String str = "Hello world1!\n";//用于写入文本的字符串
        File destDir = new File("D:/JLX/Test");//使用File封装文件路径
        if (!destDir.exists()) {//确认文件路径是否存在
            destDir.mkdirs();//不存在则逐级创建
            //destDir.mkdir();//该方法只创建一级
        }
    }
}

运行以上代码,自定义的目录就创建完成啦!此时得到的是空目录,内部还没有文件。

image.png

二、创建txt文件并向里面写入内容

创建txt文件可以使用File中的createNewFile()方法。不过这里我们使用FileWriter类来创建文件,便于过渡到文件写入部分。

  • 首先使用FileWriter创建一个空对象fw,向FileWriter(1, 2)中传入两个参数赋值给fw,第一个参数为文件路径(不是文件夹路径)比如"D:/JLX/Test/user.txt", 第二个参数为布尔值,可以不写默认为falsetrue表示以追加的方式写入文本,false则表示以覆盖的方式写入文本。

注:追加就是在已有文本的基础上在后面续写,覆盖的意思就是新内容将会覆盖原本的内容。

FileWriter fw = null;
try {
    fw = new FileWriter("D:/JLX/Test/user.txt", true);//这行代码执行完毕则txt文件创建好了
    
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        fw.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

执行这段代码后就可以得到user.txt文件啦。

image.png 到这里离成功写入文件只剩一步之遥了。

  • 调用FileWriterwrite()方法(也可以使用append()方法),传入刚开始定义的字符串str。该方法就会根据给定的内容写入目标文件。但不要掉以轻心,还有一件事!!!
  • 在最后的finally中调用close()方法!(写好new FileWriter()的时候,进行下一步,将数据写入文本。但实际上数据并没有写入文本,而是存在了计算机的流中。此时使用fw.flush()刷新,即可存入文本。但我们使用fw.close(),因为它不仅实现刷新操作,还会在刷新后关闭流!注:flush 刷新后,流可以继续使用,close刷新后,会将流关闭。)关于flushclose的解释来源于网络,大家可自行查阅。
FileWriter fw = null;
try {
    fw = new FileWriter("D:/JLX/Test/user.txt", true);//这行代码执行完毕则txt文件创建好了
    //fw.append(str);
    fw.write(str);//文件写入

} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        fw.close();//刷新并关闭流
    } catch (IOException e) {
        e.printStackTrace();
    }
}

写入成功就是下面的样子了。想要深入理解追加覆盖,多复制几条fw.write(str);运行一下就能理解了。

image.png

到这里还没有结束!给大家分享一下不使用close的方法。

  • 这个方法就是在创建FileWriter的时候将其放入try()的括号中,这是源于try/catch的特性,可以自动清空缓存。

代码如下:

 try (FileWriter fw = new FileWriter("D:/JLX/Test/stu.txt", true)) {
        fw.write(str);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

运行结果如下:

image.png

但是单纯使用FileWriter()写入虽然很方便,但是写入大量数据时速度比较慢。写入大量数据时可以搭配BufferedWriter()来加速,会更加高效。

  • FileWriter()BufferedWriter()调用write()方法时都是往缓冲区写,没有真正的往硬盘中写入数据。区别在于,前者每一次调用write()就会进行一次转码,而后者是缓冲区满了才会转码。

搭配使用的代码示例:

try (BufferedWriter bw = new BufferedWriter(new FileWriter("D:/JLX/Test/stu.txt", true))) {
    bw.write(str);
} catch (IOException e) {
    e.printStackTrace();
}

至此创建目录和写入文件就结束了。先附上这一部分完整代码:

public static void main(String[] args) {
    String str = "Hello world1!\n";//用于写入文本的字符串
    File destDir = new File("D:/JLX/Test");//使用File封装文件路径
    if (!destDir.exists()) {//确认文件路径是否存在
        destDir.mkdirs();//不存在则逐级创建
        //destDir.mkdir();//该方法只创建一级
    }

    //需要使用close的方式写入文件user.txt
    FileWriter fw = null;
    try {
        fw = new FileWriter("D:/JLX/Test/user.txt", true);
        //fw.append(str);
        fw.write(str);

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //利用try/catch特性的方式写入文件stu.txt
    try (BufferedWriter bw = new BufferedWriter(new FileWriter("D:/JLX/Test/stu.txt", true))) {
        bw.write(str);
    } catch (IOException e) {
        e.printStackTrace();
    }


}

三、从文件中读取文件内容

接下来就是最后一部分:如何从已有的文件中读取内容并显示出来。我们先看看stu.txt文件中的内容是什么:

image.png

注:如果你的文件中只有一行,以追加的方式多运行几次即可。

读取步骤:

  • 我们使用 BufferedReaderFileReader搭配的方式(写是write,读取当然是reader啦)。
  • 先将文件路径传入FileReader参数列表进行封装为一个对象,封装后我们才能调用对象的方法对文件进行操作。外层再使用 BufferedReader封装加速读取效率。最后得到的是BufferedReader对象命名为br
  • 在调用br.readLine()方法一行一行的读取数据,将读取的数据存入一个String对象中,最后打印即可。

代码如下:

public static void main(String[] args) {
    try (BufferedReader br = new BufferedReader(new FileReader("D:/JLX/Test/stu.txt"))) {//对文件封装
        String line = "";//定义空字符串用于存放数据
        line = br.readLine();//读取一行数据

        System.out.println(line);//打印数据

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}


}

输出如下:

image.png

大家发现了吗?控制台只显示了一行数据,没有将文件全部读取出来,因为我们少了循环读取的步骤:

  • 在上述基础上利用读取到的数据中非空判断,以此作为循环条件,并且将读取到的数据存入ArrayList容器中。
  • 再次打印

代码如下:

public static void main(String[] args) {
    try (BufferedReader br = new BufferedReader(new FileReader("D:/JLX/Test/stu.txt"))) {//对文件封装
        String line = "";
        ArrayList<String> arr = new ArrayList<>();//创建存储数据的容器
        while ((line = br.readLine()) != null) {//读取的数据为空则退出循环
            arr.add(line);//将每一行数据存入容器中
        }

        System.out.println(arr);

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

输出如下:

image.png

到这里相信大家已经学会文件读取了,在此基础上大家可以根据实际需要进行一些调整。我是@学安卓的老七,在此分享一点自己学习心得,希望对大家有帮助!