• 异常解决!针对文件I/O写入操作时FileNotFoundException异常的修复


    一. 异常问题

    I/O对于在Java学习路上的初学者来说,简直就是一道长长的坎儿。我们在使用I/O的过程中,会有许多的异常需要处理,并且其中还带有一系列的验证逻辑在其中。如果在学习过程中,我们的基础打得不牢靠,那么可能会由逻辑问题引发出一系列的异常。而这些类似的异常,从代码层面来检测是没有问题的,只是逻辑部分出现了问题。

    今天壹哥就以一个实际案例来给大家举例说明,下面是一段示例代码,看起来并没有什么问题。

    1. import java.io.FileNotFoundException;
    2. import java.io.FileOutputStream;
    3. import java.io.IOException;
    4. import java.io.OutputStream;
    5. public class IOTest {
    6. public static void main(String[] args) {
    7. String msg = "写入一行内容";
    8. String path = "d:/study/io/info.txt";
    9. save(path, msg);
    10. }
    11. private static void save(String path, String msg){
    12. try {
    13. OutputStream os = new FileOutputStream(path);
    14. byte[] data = msg.getBytes();
    15. os.write(data);
    16. os.flush();
    17. os.close();
    18. } catch (FileNotFoundException e) {
    19. e.printStackTrace();
    20. } catch (IOException e) {
    21. e.printStackTrace();
    22. }
    23. }
    24. }

    但运行上面的程序,却会出现如下异常:

    1. java.io.FileNotFoundException: d:\study\io\info.txt (系统找不到指定的路径。)
    2. at java.io.FileOutputStream.open0(Native Method)
    3. at java.io.FileOutputStream.open(FileOutputStream.java:270)
    4. at java.io.FileOutputStream.(FileOutputStream.java:213)
    5. at java.io.FileOutputStream.(FileOutputStream.java:101)
    6. at IOTest.save(IOTest.java:16)
    7. at IOTest.main(IOTest.java:11)

    那么上面的异常该怎么解决呢?我们继续往下看。

    二. 解决思路

    1. 异常原因

    首先查看异常信息:

    java.io.FileNotFoundException: d:\study\io\info.txt (系统找不到指定的路径。)

    从这里可以看出,上述异常是由于我们保存的路径存在问题,系统找不到这个路径。

    很多初学者看到这个信息可能会想,文件写入时不是会自动创建文件吗?怎么会找不到文件呢?凡是有此疑问的童鞋,说明你的I/O相关的基础知识有些薄弱。I/O流写文件时有一个先决条件:保证父级目录一定存在所以这里我们来查看一下,文件的父级保存路径是否存在。

     结果发现,父级目录确实不存在!所以问题就出在这里!

    说到这里,有的童鞋可能就会去手动创建目录,保证父级目录存在,这样做确实能够解决问题。

     再次运行测试,程序正常运行!

    2. 解决办法

    那么我们是不是就这样将问题解决了呢?当然不是。这里需要注意的是:save是一个方法,可以被反复调用,传递的参数也可能发生变化。换句话说,保存的内容和保存的路径都是变化的。我们总不能一直手动的去创建父级目录来保证程序的正常运行吧,所以此时我们需要使用 File类的相关知识来解决该问题。

    根据上面的描述,我们只需要能够创建出父级目录即可,而 File 类刚好提供了这样的功能。

    1. File file = new File(path);//构建文件对象
    2. File parent = file.getParentFile();//获取父级目录
    3. if(!parent.exists()){//如果父级目录不存在
    4. parent.mkdirs();//创建目录
    5. }

    只要我们将上面的代码编写在save方法中,就可以保证父级目录的存在,即使该方法被重复调用,也依然可以保持正常运行,代码如下:

    1. private static void save(String path, String msg){
    2. File file = new File(path);//构建文件对象
    3. File parent = file.getParentFile();//获取父级目录
    4. if(!parent.exists()){//如果父级目录不存在
    5. parent.mkdirs();//创建目录
    6. }
    7. try {
    8. OutputStream os = new FileOutputStream(path);
    9. byte[] data = msg.getBytes();
    10. os.write(data);
    11. os.flush();
    12. os.close();
    13. } catch (FileNotFoundException e) {
    14. e.printStackTrace();
    15. } catch (IOException e) {
    16. e.printStackTrace();
    17. }
    18. }

    然后我们可以再次更改路径,重新测试。

    1. public static void main(String[] args) {
    2. String msg = "写入一行内容";
    3. String path = "d:/study/io2/info.txt";
    4. save(path, msg);
    5. }

    再次运行,查看结果如下:

     程序依然可以正常运行!至此,我们就把整个问题解决了!

    三. 小结

    通过这个案例,我们会发现,在学习的过程中,我们的基础知识一定要牢固!其实很多异常的出现,并非是代码本身存在问题,而是一些基础知识的掌握没有跟上,导致代码缺少逻辑验证,从而引发了异常。所以基础知识薄弱的童鞋,可以在网上查阅资料进行学习。

    如果你还有其他问题,可以评论区给我留言,壹哥看到了会及时给你解答。

  • 相关阅读:
    SDUT 2022 Autumn Team Contest 7th
    基于ssm的公选课申报系统
    浅谈 Spring
    element plus 的图片上传组件回显
    JS 数据结构:链表
    如何理解Go言中的Context?
    你从浏览器输入一个URL到返回HTML界面给你这个流程发生了什么?【一文搞定吃透】
    如何使用IP归属地查询API加强网络安全
    前缀和实例1 (【模板】前缀和 )
    代码的工厂模式
  • 原文地址:https://blog.csdn.net/syc000666/article/details/128073872