Java通过流 下载文件 输出文件 Java 高性能下载文件 java 优化 下载 流 输出文件

获取resource目录资源文件 依赖

不需要获取 resource目录资源文件 不需要加这个依赖

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>


import cn.hutool.core.thread.ThreadUtil;
import com.mh.jishi.config.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import javax.activation.MimetypesFileTypeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.net.URLEncoder;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;

/**
 * <h2>下载文件工具类</h2>
 * <p>
 *
 * </p>
 *
 * @author 作者<1 9 2 2 8 0 2 3 5 2 @ qq.com>
 **/
@Slf4j
public class DownloadUtil {
    /**
     * 输出文件
     *
     * @param fileName 文件名称
     * @param file     文件对象
     * @param isDel    操作完是否删除文件, true 是,默认 true
     */
    public static void outFileByFile(String fileName, File file, Boolean isDel, HttpServletRequest request,
                                     HttpServletResponse response) {
        Assert.notNull(file, "文件不能为空");
        Assert.isTrue(file.exists(), "文件不存在");

        try {
            String type = request.getHeader("User-Agent").toLowerCase();
            String charsetCode = "UTF-8";
            if (type.indexOf("firefox") > 0 || type.indexOf("chrome") > 0) {
                fileName = new String(fileName.getBytes(charsetCode), "iso8859-1");
            } else {
                fileName = URLEncoder.encode(fileName, charsetCode);
            }
            // 设置响应的头部信息
            response.setHeader("content-disposition", "attachment;filename=" + fileName);
            // 设置响应内容的类型
            MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();

            String mimeType = fileTypeMap.getContentType(file.getName());
            response.setContentType(mimeType + "; charset=" + charsetCode);
            response.setContentLength((int) file.length());
            // 设置响应内容的长度
            response.setHeader("Content-Length", String.valueOf(file.length()));
            // 通过文件管道下载
            WritableByteChannel writableByteChannel = Channels.newChannel(response.getOutputStream());
            FileChannel fileChannel = new FileInputStream(file.getAbsolutePath()).getChannel();
            fileChannel.transferTo(0, fileChannel.size(), writableByteChannel);
            log.info("输出文件成功");
            fileChannel.close();
            writableByteChannel.close();
        } catch (Exception e) {
            log.error("输出文件异常, 异常原因: ", e);
            throw new ServiceException(e.getMessage());
        } finally {
        	// 这里使用的是 hutool线程工具 异步删除本地文件
            ThreadUtil.execAsync(() -> {
                log.info("输出文件,是否删除本地文件:【{}】", isDel);
                if (null != isDel) {
                    if (isDel) {
                        if (file.exists()) {
                            boolean isSuccessDel = file.delete();
                            log.info("输出文件,删除本地文件是否成功:【{}】", isSuccessDel);
                        }
                    }
                }
            });

        }

    }
	 /**
	     * 获取 项目Resource 目录下的文件
	     *
	     * @param filePath 文件在 resource下的路径 例如: 要获取 resource/static/a.txt 文件, filePath =
	     *                 /static/a.txt
	     * @throws IOException {@link IOException}
	     * 
	     */
	    public static File getResourceFile(String filePath) throws IOException {
	        // 获取输入流
	        Resource resource = new ClassPathResource(filePath);
	        InputStream inputStream = resource.getInputStream();
	        String outFilePath = (new File(".")).getCanonicalPath();
	        // 文件名称
	        String outFileName = String.format("/tmp-files/tmp-file-%s", System.currentTimeMillis());
	        File file = new File(outFilePath.concat(outFileName));
	        // 将inputStream 流复制输出到文件, 后续操作完文件,记得删除这个文件,避免时间久了产生太多没必要的文件, 也可以写个定时器 定时删除 过期文件
	        FileUtils.copyInputStreamToFile(inputStream, file);
	        inputStream.close();
	        return file;
	
	    }

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值