文件上传和多文件上传(使用nio)

零、文章有点长,但是很全,请耐心观看。

一、文件上传(单个)

nio是java自带的,所以不用引入其他依赖。

/**
     * 文件上传方法
     */
    public static Result uploading(MultipartFile file) {
        //获取文件名
        String realName = file.getOriginalFilename();
        String newName = null;
        if(realName != null && realName != ""){
            //获取文件后缀
            String suffixName = realName.substring(realName.lastIndexOf("."));
            //生成新名字
            newName = UUID.randomUUID().toString().replaceAll("-", "")+suffixName;
        }else {
            return Result.fail("文件名不可为空");
        }
        //创建流
        FileInputStream fis = null;
        FileOutputStream fos = null;
        //创建通道
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        try {
            fis = (FileInputStream)file.getInputStream();
            //开始上传
            fos = new FileOutputStream(UPLOAD_URL+"\\"+newName);
            //通道间传输
            inChannel = fis.getChannel();
            outChannel = fos.getChannel();
            //上传
            inChannel.transferTo(0,inChannel.size(),outChannel);

        }catch (IOException e){
            return Result.fail("文件上传路径错误");
        }finally {
            //关闭资源
            try {
                if (fis != null) {
                    fis.close();
                }
                if (fos != null) {
                    fos.close();
                }
                if (inChannel != null) {
                    inChannel.close();
                }
                if (outChannel != null) {
                    outChannel.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return Result.ok(newName);

    }

这些当然还没完事,下面我们来配置文件的上传路径,和访问路径。

二、配置文件的上传和访问路径

这些基本上能满足大部分的文件上传路径的需求,当然有的是不需要的,可以根据自己所需进行添加或者删除。

# 配置文件访问路径
uploadFile:
  # 文件本地路径
  path: D:/img/
  # 文件访问虚拟路径
  staticAccessPath: /upload/**
# 配置图片访问路径
upload-url: D:/img/
# 基于外置tomcat的访问路径
download-url: http://192.168.31.55:8081/img/
# 压缩文件存放路径
tarFilePath: D:/test/

1、虚拟访问路径的配置

如果你选择用虚拟访问路径请添加一下配置,在代码中添加一个配置类,就可以实现配置虚拟路径了。
如果你选择外置的tomcat请查看我的其他文章。

package com.wb.srpingboot.demoz.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 *
 * <p>
 * Description: 配置访问文件虚拟路径,不适用外置的tomcat
 * </p>
 *
 * @author 阿萨
 * @version v1.0.0
 * @since 2020-08-25 19:34:34
 * @see com.wb.srpingboot.demoz.config
 *
 */
@Configuration
public class UploadFilePathConfig implements WebMvcConfigurer {
    @Value("${uploadFile.path}")
    private String uploadFilePath;

    @Value("${uploadFile.staticAccessPath}")
    private String staticAccessPath;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry){
        registry.addResourceHandler(staticAccessPath).addResourceLocations("file:"+uploadFilePath);
    }
}

以上一个文件上传就可以完美运行了。

2、使用静态代码块读取路径。

在代码中,当你的变量有static修饰的时候,你使用@Value注解是注入不了的,所以我使用了静态代码块的方式。

/**UPLOAD_URL 带压缩的文件目录和文件上传路径*/
    public static String UPLOAD_URL;
    /**文件的访问路径(基于外置的tomcat图床)*/
    public static  String DOWNLOAD_URL;
    /**指定打成的tar包的名称和tar包存放的位置*/
    public static String TAR_FILE_PATH;
    /**
    *文件的虚拟访问路径(直接访问本地的文件)
     */
    public static String STATIC_ACCESS_PATH;

     /*private static Date data = new Date();
     private static SimpleDateFormat adf = new SimpleDateFormat("MM-dd");
     private static String format = adf.format(data);*/

     // 读取yml里的属性值
    static {
        YamlPropertiesFactoryBean yamlMapFactoryBean = new YamlPropertiesFactoryBean();
        //可以加载多个yml文件
        yamlMapFactoryBean.setResources(new ClassPathResource("application.yml"));
        Properties properties = yamlMapFactoryBean.getObject();
        //获取yml里的路径参数
        if (properties != null) {
            UPLOAD_URL = properties.getProperty("upload-url");
            DOWNLOAD_URL = properties.getProperty("download-url");
            TAR_FILE_PATH = properties.getProperty("tarFilePath");
            STATIC_ACCESS_PATH = properties.getProperty("uploadFile.staticAccessPath");
            if (UPLOAD_URL == null || "".equals(UPLOAD_URL)){
                throw new RuntimeException("上传路径为空");
            }
            if (DOWNLOAD_URL == null || "".equals(DOWNLOAD_URL)){
                throw new RuntimeException("访问路径为空");
            }
            if (TAR_FILE_PATH == null || "".equals(TAR_FILE_PATH)){
                throw new RuntimeException("压缩路径为空");
            }
            if (STATIC_ACCESS_PATH == null || "".equals(STATIC_ACCESS_PATH)){
                throw new RuntimeException("文件的访问虚拟路径为空");
            }
        }else {
            throw new RuntimeException("找不到名为application.yml配置文件");
        }
        //上传路径
        File targetFile = new File(UPLOAD_URL);
        //如果路径不存在就创建
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
    }

三、文件上传(一次多个)

和上面的单个文件上传没什么不同,只是多了一个循环,就不多解释了,直接上代码。

 /**
     * TODO: 文件上传(可一次上传多个文件也可以一次上传一个文件)
     * @param files 上传的文件
     * @return com.wb.srpingboot.demoz.utils.Result
     */
    public static Result uploads(MultipartFile[] files){
        if(files.length > 0 && !(files[0].isEmpty())){
            //创建流
            FileInputStream fis = null;
            FileOutputStream fos = null;
            //创建通道
            FileChannel inChannel = null;
            FileChannel outChannel = null;
            String newName;
            List<String> imgName = new ArrayList<>();
            try {
                for (MultipartFile file : files) {
                    String realName = file.getOriginalFilename();
                    //初始化文件新名字
                    if (realName != null && realName != "") {
                        //获取文件后缀
                        String suffixName = realName.substring(realName.lastIndexOf("."));
                        //生成新名字
                        newName = UUID.randomUUID().toString().replaceAll("-", "") + suffixName;
                    } else {
                        return Result.fail("文件名不可为空");
                    }

                    fis = (FileInputStream) file.getInputStream();
                    //开始上传
                    fos = new FileOutputStream(UPLOAD_URL + "\\" + newName);
                    //通道间传输
                    inChannel = fis.getChannel();
                    outChannel = fos.getChannel();
                    //上传
                    inChannel.transferTo(0, inChannel.size(), outChannel);
                    imgName.add(newName);
                }
                //打成压缩包
                //toCompress("haha");
            }catch (IOException e) {
                return Result.fail("文件上传路径错误");
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                //关闭资源
                try {
                    if (fis != null) {
                        fis.close();
                    }
                    if (fos != null) {
                        fos.close();
                    }
                    if (inChannel != null) {
                        inChannel.close();
                    }
                    if (outChannel != null) {
                        outChannel.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return Result.ok(imgName);
        }
        return Result.fail("请选择文件");
}

四、Result返回值类。

如果你是CV过去的,一定会发现Result这个类有问题,所以我在这把这个类给出来。
这个类只是为了规范一下返回值的类型,所以如果你们公司有别的规定请自行更改。

package com.wb.srpingboot.demoz.utils;

import java.io.Serializable;

/**
 * Controller中处理方法的返回值类型
 * @author as
 * @since 1.0
 */
public class Result implements Serializable {

    // 状态码
    private int code;
    // 消息
    private String message;
    // 数据
    private Object data;

    public Result() { }

    public Result(int code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public Result(int code, String message) {
        this(code, message, null);
    }

    public Result(int code, Object data) {
        this(code, null, data);
    }

    public static Result ok(String message, Object data) {
        return new Result(0, message, data);
    }

    public static Result ok(String message) {
        return new Result(0, message, null);
    }

    public static Result ok(Object data) {
        return new Result(0, null, data);
    }

    public static Result fail(String message) {
        return new Result(-1, message);
    }

    public static Result fail(String message, Object data) {
        return new Result(-1, message, data);
    }

    public static Result fail(Object data) {
        return new Result(-1, null, data);
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "Result{" +
                "code=" + code +
                ", message='" + message + '\'' +
                ", data=" + data +
                '}';
    }
}

五、完整的工具类链接

https://blog.csdn.net/han_zheng_yiqi/article/details/108243512
以上就是整个文件上传了,感谢观看。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值