SpingBoot 1.5.2,MultipartFile保存图片时的不稳定异常(好像和内置tomcat有关)

最近项目上用到图片上传,一开始我都用的是SpringMVC自带的MultipartFile来处理的,不须要本身新建流来处理,apache

MultipartFile有个方法是void transferTo(File dest) throws IOException, IllegalStateException;服务器

能够快速的处理。app

 

作的项目是SpringBoot、和Spring、SpringMVC、Mybatis框架搭建的,若是使用MultipartFile的transferTo方法,会发现不太稳定。有时候会在执行这个方法时抛出异常,表示文件或者目录不存在框架

报错信息这会儿很差找了,运维

但报错的目录是Tomcat内部的一个目录,好像是Tomcat把用本身临时目录而后由组合了咱们项目文件落地的目录去保存问价  这固然后报文件或者目录不存在。ide

 

/**
     * 保存上传文件到制定目录地址
     * 
     * @param file
     *            当前上传那文件
     * @param filePath
     *            档期保存文件目录地址(全路径),带文件名的目录地址
     * @return 返回当前保存后的文件
     * @throws IOException
     */
    public File saveFile(MultipartFile file, String filePath) throws IOException {
        LOGGER.info("ImageUtil's saveFile   进来了:{}", filePath);
        File tempFile = new File(filePath);
        if (!tempFile.getParentFile().exists()) {
            tempFile.getParentFile().mkdirs();
        }
        if (!tempFile.exists()) {
            LOGGER.info("filePath exists 时 建立 {}", filePath);
            tempFile.createNewFile();
        }
        file.transferTo(tempFile);
        return tempFile;
    }

深刻到源码内部,发现是:org.apache.catalina.core.ApplicationPart中的测试

 @Override
    public void write(String fileName) throws IOException {
        File file = new File(fileName);
        if (!file.isAbsolute()) {
            file = new File(location, fileName);
        }
        try {
            fileItem.write(file);
        } catch (Exception e) {
            throw new IOException(e);
        }
    }

这个方法抛出的错误,file.isAbsolute()认为咱们的目录不是绝对路径,而后觉得是相对路径,再去建立文件,确定会致使报错。spa

本人亲测下来发现Windows下若是保存路径写得不正确确定会出错;好比直接copy Windows目录下的E:\abc,而应该是写成:app.comment.image=E:\\abccode

可是在Linux服务器环境下,有时候(几率比较低),也会出现这种状况;暂时我尚未发现为何会这样,可是Linux下偶尔出错应该也是这个问题blog

 

记得以前有一次,慕名奇妙图片上传失败,这一块的代码没有动过,为何会出现这种状况呢,我仔细查看原来是自从上次发布以后,忽然之间图片就不能正常上传了,因此在没有深究缘由的状况下,无奈的对运维说:要不把服务重启一下,这下还真的邪门了,服务重启以后,就能够正常的传图了

 

上次是生产环境的问题,后来在测试环境中无心中也出问题了。最后果断把这个方法给改掉了;

一劳永逸的解决这个问题:

本身用流来写:

/**
     * 保存上传文件到制定目录地址
     * 
     * @param file
     *            当前上传那文件
     * @param filePath
     *            档期保存文件目录地址(全路径),带文件名的目录地址
     * @return 返回当前保存后的文件
     * @throws IOException
     */
    public File saveFile(MultipartFile file, String filePath) throws IOException {
        LOGGER.info("ImageUtil's saveFile{}: ", filePath);

        // file.transferTo(tempFile);
        // return tempFile;
        File tempFile = new File(filePath);
        if (!tempFile.getParentFile().exists()) {
            boolean mkdirs = tempFile.getParentFile().mkdirs();
            LOGGER.info("--------建立父目录:{}", mkdirs);
        }
        try (BufferedOutputStream buffStream = new BufferedOutputStream(new FileOutputStream(tempFile))) {
            byte[] bytes = file.getBytes();
            buffStream.write(bytes);
            buffStream.flush();
        }
        return tempFile;
    }
相关文章
相关标签/搜索