首页 > 其他分享 >文件上传transferTo一行代码的bug

文件上传transferTo一行代码的bug

时间:2022-11-16 22:58:04浏览次数:44  
标签:transferTo File fileName file new path 上传 bug

transferTo

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

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

Spring 大哥真的是强大。

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

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

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

  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的源码中不会根据你给的路径自动创建图片的上一层路径。

标签:transferTo,File,fileName,file,new,path,上传,bug
From: https://www.cnblogs.com/kisshappyboy/p/16897842.html

相关文章

  • 联调神器,处理你未考虑到的bug。打日志,请求日志
    目录:1、ErrorAopAdvicepackagesj.aopLog;importcom.alibaba.fastjson.JSON;importcom.alibaba.fastjson.serializer.SerializerFeature;importlombok.extern.sl......
  • 使用Metaweblog上传MD文件到博客园遇到的几个问题
    can'topenfile'upload.py':[Errno2]Nosuchfileordirectory分析:upload.py文件在pycnblog源代码文件夹下,而cmd命令的执行路径是C:\WINDOWS\System32,所以提示找不......
  • linux安装lrzsz命令用于文件上传下载
    废话不多说,直接上嘴简单方便的命令:1-首先更新一下apt-get:(apt-get属于linux默认命令,但是预装的可能不是最新版本)apt-getupdate2-使用apt-get安装lrzsz命令:apt-get-......
  • aspnetcore两种上传图片(文件)的方式
    aspnetcore上传图片也就是上传文件有两种方式,一种是通过form-data,一种是binary。先介绍第一种form-data:该方式需要显示指定一个IFormFile类型,该组件会动态通过打开一个w......
  • 下错jdk压缩包用rz上传到Linux乱码
    哭泣32位的JDK上传到64位的Centos,一开始上传就是乱码,然后网上说是因为上传压缩包要加参数rz-be,其实下对包就不用下载的是jdki586,三年了我还不知道这个32为的包rm:r......
  • IDEA debug时拷贝数据 Evaluate Expression窗口
    今日份鸡汤:别人再好,也是别人。自己再不堪,也是自己,独一无二的自己。只要努力去做最好的自己,一生足矣。为自己的人生负责,为自己的梦想买单。用IDEA调试时候经常需要拷贝变......
  • GIT-LFS(解决大于100M的文件无法上传的问题)
    1.什么是GIT-LFSGitLFS(LargeFileStorage)是一个开源的Git大文件版本控制的解决方案和工具集,工具自身是基于Golang进行实现,并在Github上开源。原理上是通过对Git客户......
  • 聊聊Hive数据血缘——从Atlas没有列级血缘的Bug讲起
    前几天,Datahub提供了最新的字段级别数据血缘功能,很多朋友迫不及待想对比一下Datahub的字段级血缘与Atlas的区别。这个时候问题来了,在Atlas收集Hive血缘的时候,由于部分版本......
  • 关于pycharm中出现的一个小bug
    在pycharm中启动项目,一般直接点击pycharm右上进行配置下,然后点击右边的小三角。结果一直报错。  这个报错,很明显,可以看出启动的是该文件,所以应该找到启动文件manage.p......
  • Java SpringBoot FTP 上传下载文件
    POM添加依赖<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.3.7</version></dependency><!--......