ftp服务器批量下载文件之retrieveFileStream (方式一)

1.首先先说一下这些坑:(组合套装)

标题

这个行代码一定要注意, 而且随时打印code码,以便确认错误.

2.大致思路:

3. 先根据ID查询出来url

@RequestMapping(value="test1", produces = "text/plain;charset=UTF-8")
public void test2(HttpServletRequest request ,HttpServletResponse response){
        try {
            
                List<Map<String, Object>> queryForList = jdbcTemplate.queryForList(" select url from tb_work_record where FIND_IN_SET(wr_id,'1,2')  ");
                List<String> filePaths=new ArrayList<String>();
                for (int i = 0; i < queryForList.size(); i++) {
                    filePaths.add(queryForList.get(i).get("url").toString());
                }
                test2(request, response, filePaths);
        } catch (Exception e) {
            e.printStackTrace();
        }
}

4.压缩 ,调用浏览器下载,删除 web服务器临时产生zip文件

public void test2(HttpServletRequest request ,HttpServletResponse response,List<String> filePaths){

           //根据url获取文件流压缩到zip文件中(重点中的重点)
            String  zipFilePath = copy(filePaths);
            //调用浏览器下载
            template(response, zipFilePath);

            删除 web服务器临时产生zip文件
            new File(zipFilePath);
    }

5.//根据url获取文件流压缩到zip文件中

5-1.首先去ftp服务器上循环拿到文件流和文件名,

5-2.循环拿的同时循环写入到web服务器中的zip文件(可能有人要问为什么循环拿的同时要去循环写入呢? 因为每次 InputStream in = ftp.retrieveFileStream(path)  时 in都要close之后才能重新调用retrieveFileStream方法, 如果不close ,则会在第二次时in为null,或者直接假死, 但是你不能把in.close(),之后 再去调BufferedInputStream输出流写入到zip中 ,所以必须边循环拿流边循环写入到zip)

public String copy(List<String> remotePath) {
        Map<String, Object> map = new HashMap<>();
        FTPClient ftp = new FTPClient();
        String zipBasePath = "E://upload"; //web服务器地址

         
        String zipName =" test.zip";
        String zipFilePath = zipBasePath + File.separator + zipName;//web服务器zip文件地址
        try {

            File zip = new File(zipFilePath);//在web服务器上创建文件
            if (!zip.exists()) {
                zip.createNewFile();
            }
            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip));

            // 创建FTPClient对象
            String host = "172.168.31.123";
            Integer port = 21;
            String username = "******";
            String password = "*******";
            // 连接FTP服务器
            // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
            ftp.connect(host, port);
            // 登录ftp
            ftp.login(username, password);
            ftp.setControlEncoding("UTF-8"); // 中文支持
            ftp.enterLocalPassiveMode();//一定要加上
            for (int j = 0; j < remotePath.size(); j++) {
                String path = remotePath.get(j);
                ftp.changeWorkingDirectory("/");
                String fileName = StringUtils.substringAfterLast(remotePath.get(j), "/");
                InputStream in = ftp.retrieveFileStream(path);//拿到流
                map.put("io", in);
                map.put("name", URLDecoder.decode(fileName, "UTF-8"));
                zipFileList(zipBasePath, zipName, zipFilePath, map, zos); //没关闭in之前,先写入到zip中
                in.close();
                ftp.completePendingCommand();
                System.out.println(ftp.getReplyCode());
            }
            zos.close();
        } catch (Exception e) {
            System.out.println(ftp.getReplyCode());
            e.printStackTrace();
        }
        return zipFilePath;
    }

6.将流依次写入到zip文件中

 

private void zipFileList(String zipBasePath, String zipName, String zipFilePath, Map<String, Object>  filePaths,ZipOutputStream zos) throws IOException {
        InputStream in=(InputStream)filePaths.get("io");
        BufferedInputStream bis = new BufferedInputStream(in);  
        
        //将文件写入zip内,即将文件进行打包  
        zos.putNextEntry(new ZipEntry(filePaths.get("name").toString()));  //这里可以修改要写入到zip中文件的名称
        
        //写入文件的方法,同上                  
        int size = 0;  
        byte[] buffer = new byte[1024];  //设置读取数据缓存大小
        while ((size = bis.read(buffer)) > 0) {  
            zos.write(buffer, 0, size);  
        }  
        //关闭输入输出流  
        zos.closeEntry();  
        bis.close(); 
         
    } 

7.调用浏览器下载

public void template(HttpServletResponse response ,String downLoadPath){
        try {
            String fileName=downLoadPath.substring(downLoadPath.lastIndexOf("/")+1);
            byte[] buffer=null;  
            buffer =downFileByte(downLoadPath) ; 
            String fileSuffixName=   fileName.substring(fileName.lastIndexOf(".")+1);
            response.reset(); //清除缓存
            response.setContentType("application/" +fileSuffixName + ";" +"charset = UTF-8"); //设置字符集和文件后缀名
            String name=id.nextId()+"";
            name = new String(name.getBytes(), "ISO-8859-1");
            response.setHeader("Content-Disposition","attachment; filename=" +name+"."+fileSuffixName); // 设置文件名称
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());  
            toClient.write(buffer);  
            toClient.flush();  
            toClient.close();
        } catch (Exception e) {
            e.printStackTrace();
            Log4jUtil.getLog4jUtil().error("下载zip文件异常"+e.getMessage());
        }
    }

8.工具类

public static byte[] downFileByte(String downLoadPath) throws Exception{  
        byte[] return_arraybyte=null;  
        InputStream ins=new FileInputStream(downLoadPath );  
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();  
        byte[] buf = new byte[1024];  
        int bufsize = 0;  
        while ((bufsize = ins.read(buf, 0, buf.length)) != -1) {  
            byteOut.write(buf, 0, bufsize);  
        }  
        return_arraybyte = byteOut.toByteArray();  
        byteOut.close();  
        ins.close();  
    return return_arraybyte;  
    }

 

感觉可以用到的连接:

code码:https://blog.csdn.net/jinhao2003/article/details/2141378

ftp主被动连接:https://www.cnblogs.com/huhaoshida/p/5412615.html 

in.close坑解释连接:https://www.e-learn.cn/content/java/758171

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10000guo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值