java下载文件或文件夹

java下载文件或文件夹最近接到一个需求,就是将远程目录下的文件或文件夹下载到指定目录下,下面来看下最后的成果。1.首先,IO流输出文件(可以在浏览器端下载)publicHttpServletResponsedownload(StringfileName,HttpServletResponseresponse){Filefile=newFile(gitConfig.getDestPath()+”/”+fileName);if(file.isDirec

大家好,又见面了,我是你们的朋友全栈君。

最近接到一个需求,就是将远程目录下的文件或文件夹下载到指定目录下,下面来看下最后的成果。

1.首先,IO流输出文件(可以在浏览器端下载)

   public HttpServletResponse download(String fileName, HttpServletResponse response) {
        File file = new File(gitConfig.getDestPath() + "/" + fileName);
        if (file.isDirectory()){
            return downDestroy(file, response);
        }else{
            return downFile(file,response);
        }

    }

    /**
     * 下载文件
     * @param file
     * @param response
     * @return
     */
    private HttpServletResponse downFile(File file, HttpServletResponse response) {
        InputStream fis = null;
        OutputStream toClient = null;
        try {
            // 以流的形式下载文件。
            fis = new BufferedInputStream(new FileInputStream(file.getPath()));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            // 清空response
            response.reset();
            toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            //如果输出的是中文名的文件,在此处就要用URLEncoder.encode方法进行处理
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
            toClient.write(buffer);
            toClient.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        }finally{
            try {
                File f = new File(file.getPath());
                f.delete();
                if(fis!=null){
                    fis.close();
                }
                if(toClient!=null){
                    toClient.close();
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return response;
    }

    /**
     * 下载文件夹
     * @param file
     * @param response
     * @return
     */
    private HttpServletResponse downDestroy(File file, HttpServletResponse response) {
        String zipFilePath = gitConfig.getDestPath()+"/"+file.getName()+"_"+System.currentTimeMillis()/1000+".zip";
        ZipCompressor zipCompressor = new ZipCompressor(zipFilePath);
        try {
            zipCompressor.compress(file.getPath());
            File zipFile = new File(zipFilePath);
            downFile(zipFile,response);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }

对应的工具类


import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 压缩类
 *
 */
public class ZipCompressor {

    static final int BUFFER = 8192;

    /**
     * 压缩的文件夹
     */
    private File zipFile;

    public ZipCompressor(String pathName) {
        zipFile = new File(pathName);
    }


    /**
     * 遍历需要压缩文件集合
     * @param pathName
     * @throws IOException
     */
    public void compress(String... pathName) throws IOException {
        ZipOutputStream out =null;
        FileOutputStream fileOutputStream=null;
        CheckedOutputStream cos=null;
        try {
            fileOutputStream = new FileOutputStream(zipFile);
            cos = new CheckedOutputStream(fileOutputStream,new CRC32());
            out = new ZipOutputStream(cos);
            String basedir = "";
            for (int i=0;i<pathName.length;i++){
                compress(new File(pathName[i]), out, basedir);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            if(out!=null){
                out.close();
            }
            if(fileOutputStream!=null){
                fileOutputStream.close();
            }
            if(cos!=null){
                cos.close();
            }
        }
    }
    /**
     * 压缩
     * @param file
     * @param out
     * @param basedir
     */
    private void compress(File file, ZipOutputStream out, String basedir) throws IOException {
        // 判断是目录还是文件
        if (file.isDirectory()) {
            this.compressDirectory(file, out, basedir);
        } else {
            this.compressFile(file, out, basedir);
        }
    }
    /**
     * 压缩一个目录
     * */
    private void compressDirectory(File dir, ZipOutputStream out, String basedir) throws IOException {
        if (!dir.exists()){
            return;
        }
        File[] files = dir.listFiles();
        for (int i = 0; i < files.length; i++) {
            // 递归
            compress(files[i], out, basedir + dir.getName() + "/");
        }
    }
    /**
     * 压缩一个文件
     *
     * */
    private void compressFile(File file, ZipOutputStream out, String basedir) throws IOException {
        if (!file.exists()) {
            return;
        }
        BufferedInputStream bis =null;
        try {
            bis = new BufferedInputStream(new FileInputStream(file));
            ZipEntry entry = new ZipEntry(basedir + file.getName());
            out.putNextEntry(entry);
            int count;
            byte[] data = new byte[BUFFER];
            while ((count = bis.read(data, 0, BUFFER)) != -1) {
                out.write(data, 0, count);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            if(bis!=null){
                bis.close();
            }
        }
    }
}

2.接收IO文件流,并保存到本地(文件夹类接收的是压缩文件,接收完之后会将压缩文件解压然后删除压缩文件)

    public void downFileOrDestroy(String fileName){
        boolean isfile = true;
        if (fileName.indexOf(".")==-1){
            //如果是文件夹
            isfile =false;
        }
        String pluginsDir = "D:/file";
        URL urlfile = null;
        HttpURLConnection httpUrl = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        File path = new File(pluginsDir);
        if (!path.exists()){
            path.mkdirs();
        }
        File f = null;
        if (isfile){
            f = new File(pluginsDir+"/"+fileName);
        }else{
            f = new File(pluginsDir+File.separator+fileName+"_"+System.currentTimeMillis()/1000+".zip");
        }
        try {
            urlfile = new URL("文件IO输出接口地址?fileName="+fileName);
            httpUrl = (HttpURLConnection) urlfile.openConnection();
            httpUrl.connect();
            InputStream inputStream = httpUrl.getInputStream();
            bis = new BufferedInputStream(inputStream);
            FileOutputStream fileOutputStream = new FileOutputStream(f);
            bos = new BufferedOutputStream(fileOutputStream);
            int len = 2048;
            byte[] b = new byte[len];
            while ((len = bis.read(b)) != -1) {
                bos.write(b, 0, len);
            }
            bos.flush();
            bos.close();
            bis.close();
            httpUrl.disconnect();
            if (!isfile){
                //如果是文件夹,下载下来的是压缩文件,要解压文件
                ZipUtil.unZipUncompress(f.getPath(),pluginsDir);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bis.close();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

涉及到的工具类:

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * @Author cs
 * @Date 2020/12/31 11:51
 * @Version 1.0
 */
public class ZipUtil {

    /**
     * zip文件解压
     * @param inputFile  待解压文件夹/文件
     * @param destDirPath  解压路径
     */
    public static void unZipUncompress(String inputFile,String destDirPath){
        File srcFile = new File(inputFile);//获取当前压缩文件
        InputStream is = null;
        FileOutputStream fos = null;
        try{
            // 判断源文件是否存在
            if (!srcFile.exists()) {
                throw new Exception(srcFile.getPath() + "所指文件不存在");
            }
            ZipFile zipFile = new ZipFile(srcFile);//创建压缩文件对象
            //开始解压
            Enumeration<?> entries = zipFile.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
                // 如果是文件夹,就创建个文件夹
                if (entry.isDirectory()) {
                    srcFile.mkdirs();
                } else {
                    // 如果是文件,就先创建一个文件,然后用io流把内容copy过去
                    File targetFile = new File(destDirPath + "/" + entry.getName());
                    // 保证这个文件的父文件夹必须要存在
                    if (!targetFile.getParentFile().exists()) {
                        targetFile.getParentFile().mkdirs();
                    }
                    targetFile.createNewFile();
                    // 将压缩文件内容写入到这个文件中
                    is = zipFile.getInputStream(entry);
                    fos = new FileOutputStream(targetFile);
                    int len;
                    byte[] buf = new byte[1024];
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                    }
                    // 关流顺序,先打开的后关闭
                    fos.close();
                    is.close();
                }
            }
            zipFile.close();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //删除压缩文件
            boolean delete = srcFile.delete();
            System.out.println(delete);
        }
    }
}

有的朋友可能会遇到临时文件删除不掉的问题,一般出现这种情况的原因都是IO没关闭,检查下自己的代码,先打开的IO后关闭,按顺序关闭IO即可解决。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/156955.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • android .dex文件探究

    android .dex文件探究在我们写Java代码的时候,生成的文件是.java文件,但是JVM并不识别这个,所以会先转成class文件,而在Android端,Android上的Davlik虚拟机能运行.dex。所以dex文件中包含了所有的app代码,可利用反编译工具获取java代码。即dex文件就是AndroidDalvik虚拟机运行的程序。为了能够加深印象,我们先构造一个dex文件。publicclassDEX…

  • 存算一体——后摩尔时代的AI芯片架构[通俗易懂]

    存算一体——后摩尔时代的AI芯片架构[通俗易懂]存算一体,或存内计算,是指将传统冯诺依曼架构中以计算为中心的设计,转变为以数据存储为中心的设计,也就是利用存储器对数据进行运算,从而避免数据搬运产生的“存储墙”和“功耗墙”,极大提高数据的并行度和能量效率。这种架构特别适用于要求大算力、低功耗的终端设备,如可穿戴设备、移动设备、智能家居等。1.冯诺依曼架构的局限首先是性能。经典的冯诺依曼架构下,数据的存储和计算是分开的,处理器CPU存储器之间通过数据总线进行数据交换。但由于处理器和存储器的内部结构、工艺和封装不同,二者的性能也存在很大的差.

  • 都2022了,不会还有人不会idea注释相关的配置吧,速进本文

    都2022了,不会还有人不会idea注释相关的配置吧,速进本文####缘由  相信大家在写代码的时候,为了可以让自己明白以及他人可以明白,都会都在项目代码中加上注释,写注释也是有讲究的,注释分为两种,一种类注释,另一种方法注释。![在这里插入图片描述](https://img-blog.csdnimg.cn/2f8cde1992434945b1875114529607f6.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iqd5aOr5

  • 1. CMake 系列 – 从零构建动态库和静态库

    1. CMake 系列 – 从零构建动态库和静态库

    2021年11月22日
  • python发明人为什么退出_64岁Python创始人突然不退休了,只想做一名微软的打工人,原来是这样的!…

    python发明人为什么退出_64岁Python创始人突然不退休了,只想做一名微软的打工人,原来是这样的!…随着人工智能的飞速发展,Python横扫各大编程语言榜单,成为最受欢迎的、使用最广泛的程序设计语言之一,作为Python的创建者,GuidovanRossum突然于去年10月宣布将要退休,退出Python核心决策层。而就在今天,他在Twitter上正式宣布,退休太无聊,已加入了微软开发者部门,将致力于“确保更好地使用Python(不仅限于Windows)。据了解,他与…

  • Matlab画图-非常具体,非常全面

    Matlab画图-非常具体,非常全面

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号