java.io.FileNotFoundException Is a directory transferTo

本次的项目环境为 Running with Spring Boot v1.5.10.RELEASE, Spring v4.3.14.RELEASE, 服务器环境为CentOS7.0.

transferTo

我们在上传文件的时候会用到transferTo 这个方法,

transferTopackage org.springframework.web.multipart;帮我们已经封装好,所以我们上传文件的时候是很方便的,只需要一行代码。

Spring 大哥真的是强大。

今天我们上传的时候老是报错,错误提示

java.io.IOException: java.io.FileNotFoundException: /opt/xxxxxxx/xxx.png (Is a directory)

蹩脚的英文好好的翻译一下,xxx.png 是一个目录。

对的,看到这里大家大概就明吧了。

  String path = FILE_PATH + PATH_NAME + File.separator + dirName;
        String fileName = file.getOriginalFilename();
        ======>注意这里等下要讲的
        File targetFile = new File(path , fileName);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
        boolean upState = false;
        try {
            file.transferTo(targetFile);
            upState = true;
        } catch (IOException e) {
            log.error("file transferTo e", e);
            e.printStackTrace();
        }

分析下

其实这个这里上传文件只是一个方法,用到了 Spring自己封装的MultipartFile类,上传只是用到了transferTo,参数是文件的路径。

好了,来一步步调试看源码。

  • 第一步看transferTo中的源码
public void transferTo(File dest) throws IOException, IllegalStateException {
             ======>注意这里调用的是part 类中的write 方法,参数是File的路径
            this.part.write(dest.getPath());
            if (dest.isAbsolute() && !dest.exists()) {
                FileCopyUtils.copy(this.part.getInputStream(), new FileOutputStream(dest));
            }
        }
  • 第二步看 ApplicationPart 中的write方法
public void write(String fileName) throws IOException {
        File file = new File(fileName);
        if (!file.isAbsolute()) {
            file = new File(this.location, fileName);
        }

        try {
            this.fileItem.write(file);
        } catch (Exception var4) {
            throw new IOException(var4);
        }
    }

大家注意看第二步中的 if (!file.isAbsolute()),是的问题就在这里。

这时候如果!file.isAbsolute()成立,也就是我们没有使用绝对路径,那么file = new File(location,fileName);

这个时候会创建一个新的路径,看下面的代码

 public File(File parent, String child) {
        if (child == null) {
            throw new NullPointerException();
        }
        if (parent != null) {
            if (parent.path.equals("")) {
                this.path = fs.resolve(fs.getDefaultParent(),
                                       fs.normalize(child));
            } else {
                this.path = fs.resolve(parent.path,
                                       fs.normalize(child));
            }
        } else {
            this.path = fs.normalize(child);
        }
        this.prefixLength = fs.prefixLength(this.path);
    }

看到这里应该了解了/opt/xxxxxxx/xxx.png ,这个图片被当成文件夹了,在这里创建了一个文件夹,而不是图片。

解决方法

  • 代码注入,修改源码中的location
    @Bean
    MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        factory.setLocation(你的上传路径path);
        return factory.createMultipartConfig();
    }

 
  • 文件上传时候创建文件
    String path = FILE_PATH + PATH_NAME + File.separator + dirName;
        String fileName = file.getOriginalFilename();
         ======> 注意要先创建图片的目录mkdirs
        File sourceFile = new File(path);
        if (!sourceFile.exists()) {
            sourceFile.mkdirs();
        }

        File targetFile = new File(path + File.separator + fileName);

        boolean upState = false;
        try {
            file.transferTo(targetFile);
            upState = true;
        } catch (IOException e) {
            log.error("file transferTo e", e);
            e.printStackTrace();
        }

结论

这里其实就是 new File(path + File.separator + fileName)的问题,因为Spring的源码中不会根据你给的路径自动创建图片的上一层路径。

写这个就是要说明,遇到问题的时候要多读源码,一步步的调试。

当你一步步接近真相的时候,你会感觉到很有成就感,就像爬过一座山头一样。

多读源码 ,不要只是拷贝,很多场景拷贝的时候细节问题不一样的。

### 回答1: 嵌套异常是java.io.filenotfoundexception。 这个异常表示在尝试打开文件时找不到指定的文件。可能是文件名拼写错误、文件不存在或没有足够的权限访问文件。需要检查文件路径和文件名是否正确,并确保程序有足够的权限访问文件。 ### 回答2: "nested exception is java.io.filenotfoundexception"表示嵌套异常是java.io.filenotfoundexceptionjava.io.filenotfoundexception是一个文件找不到的异常,通常在文件操作时会出现。主要原因是程序无法找到指定路径下的文件。 当程序尝试打开或操作一个文件时,它会在指定路径下查找该文件。如果文件不存在,就会抛出java.io.filenotfoundexception异常。这可能是由于文件被删除、路径出错、文件名错误或者访问权限不足等原因引起的。 为了解决这个问题,我们应该首先检查文件路径和文件名是否正确。确保文件确实存在于指定的路径中,并且文件名大小写是否正确。 此外,还要注意程序用户是否具有足够的权限来访问该文件。有些文件可能设置了特定的访问权限,如果当前用户没有适当的权限,就无法打开或操作该文件。 如果确认文件路径、文件名和访问权限都没有问题,那么可能是由于文件确实被删除或者路径被移动引起的。这种情况下,我们需要恢复文件或者更新程序中的文件路径。 总之,"nested exception is java.io.filenotfoundexception"告诉我们出现了一个文件找不到的异常,需要检查文件路径、文件名和访问权限等相关因素,以便解决此问题。 ### 回答3: nested exception is java.io.filenotfoundexception是一个异常的嵌套异常。它表示在Java程序中,找不到指定的文件。 当程序在读取或写入文件时,如果指定的文件不存在,就会抛出这个异常。这个异常表示程序尝试访问文件系统中不存在的文件。 这个异常可能是由以下几种原因引起的: 1. 文件路径错误:程序提供的文件路径可能是错误的。文件路径应该是文件在系统中的准确位置。 2. 文件名称错误:程序提供的文件名称可能是错误的。程序应该提供正确的文件名称,包括文件的扩展名。 3. 文件不存在或已删除:程序所需访问的文件可能已经被删除或不存在于指定的位置。在使用文件之前,应确认文件是否存在。 4. 文件权限限制:程序可能没有足够的权限来访问指定的文件。在访问文件之前,应该检查程序是否具有足够的权限。 当出现nested exception is java.io.filenotfoundexception时,可以通过以下方式来解决这个问题: 1. 检查文件路径和名称是否正确。 2. 确认文件是否存在于指定的位置。 3. 检查程序是否具有足够的权限来访问文件。 4. 如果文件确实不存在,可以考虑创建一个新的文件。 总之,nested exception is java.io.filenotfoundexception表示无法找到指定的文件,并提供了一些可能的原因和解决方案。在编写Java程序时,我们应该小心处理这个异常,以确保程序可以正确地访问和处理文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值