Fastdfs功能-批量打包下载

本篇功能是基于Fastdfs文件上传下载功能,作出的将文件打包成一个zip文件下载下来。
页面效果如下


前台界面.png

选择行,点击批量下载按钮,然后就会将所有的文件打包成一个File.zip文件下载下来。解压zip文件夹,就能看到里面包含了下载的所有文件。这种下载方式不局限于xlsx文件,图片格式,文本格式,Java文件等都可以使用这种方式下载下来。

文件下载界面.png

前台代码

  //批量下载
            function downloadFunction() {
                var selected = grid.selectedDataItems();
                if(selected.length>0) {
                    kendo.ui.showConfirmDialog({
                        title: "提示",
                        message: "确定要下载?"
                    }).done(function(event) {
                        if (event.button == "OK") {
                            var recpIdList = new Array();
                            $.each(selected,function(i,v){
                                recpIdList.push(v.recpId);
                            });
                            debugger;
                            window.location.href="${base.contextPath}/ect/fut/receipt/batchDownload?recpIdList="+recpIdList;
                        }});
                }else{
                    kendo.ui.showWarningDialog({
                        message:"请至少选择一行"
                    })
                }
            }

上述是批量下载功能函数,第一步是获取所有行,如果没有选择行,将弹出警告框“请至少选择一行”,第二步,根据所选行去查询文件的服务器路径以及文件名,假如路径都为空,则下载一个空的zip文件,不为空,则将文件打包成zip格式下载。

后台代码

List<ZipModel> zipModelList = new ArrayList<>();
for (Long recpId : recpIds) {
    FutReceipt futReceipt = new FutReceipt();
    futReceipt.setRecpId(recpId.floatValue());
    futReceipt = futReceiptMapper.selectByPrimaryKey(futReceipt);
    //todo:仓单表主键不能为空并且文件不能为空
    if (futReceipt.getRecpId() != null && futReceiptMapper.getFilePathById(futReceipt.getRecpId()) != null) {
        try {
            ZipModel zipModel = new ZipModel();
            String filePatch = getFilePatch(futReceipt, requestContext);
            //todo:存储文件路径
            zipModel.setFilePath(filePatch);
            //todo:获取文件后缀,并且将仓单批次作为文件名
            zipModel.setFileName(futReceipt.getBatchNum() + filePatch.substring(filePatch.indexOf(".") + 1));
            zipModelList.add(zipModel);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
//todo:设置打包后的文件名
String fileName = "File.zip";
//todo:临时文件目录,用于存储打包的下载文件
String globalUploadPath = request.getSession().getServletContext().getRealPath("/");
String outFilePath = globalUploadPath + File.separator + fileName;
File file = new File(outFilePath);
//文件输出流
FileOutputStream outStream = new FileOutputStream(file);
//压缩流
ZipOutputStream toClient = new ZipOutputStream(outStream);
//todo:调用通用方法下载fastfds文件,打包成zip文件
ZipUtil.zipFile(zipModelList, toClient);
toClient.close();
outStream.close();
response.setHeader("content-disposition", "attachment;fileName=" + fileName);
//todo:将zip文件下载下来
ZipUtil.downloadZip(file, response);

实现步骤主要是将所有的fastdfs的文件路径和文件名存储到一个zipModelList对象中。然后先调用通用方法zipFile将这些文件下载下来打包成一个zip文件,放在一个临时存储位置,最后再通过通用方法downloadZip将文件下载下来。

存储数据对象
ZipModel.Java

public class ZipModel {

    /**
     * 文件名
     */
    private String fileName;

    /**
     * 文件在fastdfs文件服务器路径
     */
    private String filePath;

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getFilePath() {
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }
}

通用生成下载zip方法
ZipUtil.Java


public class ZipUtil {
    private static String IFastdfsService = "hfastdfs.fastdfsfile.service.IFastdfsService";

    /**
     * 压缩文件列表中的文件
     *
     * @param files
     * @param outputStream
     * @throws IOException
     * @throws ServletException
     */
    public static void zipFile(List<ZipModel> files, ZipOutputStream outputStream) throws IOException {
        try {
            int size = files.size();
            //压缩列表中的文件
            for (int i = 0; i < size; i++) {
                ZipModel zipModel = files.get(i);
                try {
                    zipFile(zipModel, outputStream);
                } catch (Exception e) {
                    continue;
                }
            }
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * 将文件写入到zip文件中
     *
     * @param zipModel
     * @param outputstream
     * @throws IOException
     * @throws ServletException
     */
    public static void zipFile(ZipModel zipModel, ZipOutputStream outputstream) throws AppException, IOException, MyException {
        try {
            if (zipModel != null && zipModel.getFilePath() != null && zipModel.getFileName() != null) {
                IFastdfsService iFastdfsService = (IFastdfsService) getBean(IFastdfsService);
                InputStream bInStream = new ByteArrayInputStream(iFastdfsService.getFile(zipModel.getFilePath()));
                ZipEntry entry = new ZipEntry(zipModel.getFileName());
                outputstream.putNextEntry(entry);

                final int MAX_BYTE = 10 * 1024 * 1024; //最大的流为10M
                long streamTotal = 0;      //接受流的容量
                int streamNum = 0;      //流需要分开的数量
                int leaveByte = 0;      //文件剩下的字符数
                byte[] inOutbyte;       //byte数组接受文件的数据

                streamTotal = bInStream.available();      //通过available方法取得流的最大字符数
                streamNum = (int) Math.floor(streamTotal / MAX_BYTE); //取得流文件需要分开的数量
                leaveByte = (int) streamTotal % MAX_BYTE;    //分开文件之后,剩余的数量

                if (streamNum > 0) {
                    for (int j = 0; j < streamNum; ++j) {
                        inOutbyte = new byte[MAX_BYTE];
                        //读入流,保存在byte数组
                        bInStream.read(inOutbyte, 0, MAX_BYTE);
                        outputstream.write(inOutbyte, 0, MAX_BYTE); //写出流
                    }
                }
                //写出剩下的流数据
                inOutbyte = new byte[leaveByte];
                bInStream.read(inOutbyte, 0, leaveByte);
                outputstream.write(inOutbyte);
                outputstream.closeEntry(); 
                bInStream.close(); //关闭
            }
        } catch (IOException e) {
            throw e;
        }
    }

    /**
     * 下载打包的文件
     *
     * @param file
     * @param response
     */
    public static void downloadZip(File file, HttpServletResponse response) {
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            // 以流的形式下载文件。
            BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();

            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
            file.delete();  //将生成的服务器端文件删除
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 获得bean,通过ApplicationContext获取
     *
     * @return
     */
    public static Object getBean(String className) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        ServletContext sc = request.getSession().getServletContext();
        ApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
        Class c;
        try {
            c = Class.forName(className);
            return ac.getBean(c);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

以上就是fastdfs文件下载的全部方法

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容