使用commons-net来下载文件(仅做记录)

使用 commons-net-3.6.jar

public class ApacheFtpUtil {
    private Logger log = LoggerFactory.getLogger(ApacheFtpUtil.class);
    private String host;
    private String username;
    private String password;
    // 控制端口
    private int port = 21;

    // 秒数
    private int defaultTimeoutSecond = 60;
    private int connectTimeoutSecond = 30;
    private int dataTimeoutSecond = 30;
    // 秒
    private int controlKeepAliveTimeout = 120;

    private boolean isTextMode = false;

    private String tranEncoding = "GB2312";

    private FTPClient client;

    public ApacheFtpUtil(String host, String username, String password) {
        this(host, username, password, 21, 0);
    }

    public ApacheFtpUtil(String host, String username, String password, int port) {
        this(host, username, password, port, 0);
    }

    public ApacheFtpUtil(String host, String username, String password, int port, int security) {
        this.host = host;
        this.port = port;
        this.username = username;
        this.password = password;
    }

    public void initClint() throws Exception {
        // FTPSClient
        client = new FTPClient();

        // 每大约2分钟发一次noop,防止大文件传输导致的控制连接中断
        client.setControlKeepAliveTimeout(controlKeepAliveTimeout);
        // client.setListHiddenFiles(listHiddenFiles);
        // FTPClientConfig config = new
        // FTPClientConfig(FTPClientConfig.SYST_NT);
        // config.setServerLanguageCode("zh");
        // config.setUnparseableEntries(saveUnparseable);
        // config.setDefaultDateFormatStr(defaultDateFormat);
        // config.setRecentDateFormatStr(recentDateFormat);
        // client.configure(config);

        // 设置默认超时
        client.setDefaultTimeout(defaultTimeoutSecond * 1000);
        // 连接超时
        // client.setConnectTimeout(connectTimeoutSecond * 1000);
        // 设置数据超时
        // client.setDataTimeout(dataTimeoutSecond * 1000);
        /*
         * socket超时 设置一个命令执行后最大等待Server反馈的时间. 如果对方连接状态60秒没有收到数据的话强制断开客户端
         */
        // client.setSoTimeout(60 * 1000);
        // client.setBufferSize(1024);
        // 连接到远程的FTP服务器.
        try {
            client.connect(this.host, this.port);
        } catch (Exception e) {
            this.destory();
            log.error("连接服务器失败,host:{}, port:{}", this.host, this.port);
            throw e;
        }
        int reply = client.getReplyCode(); // 获得返回的代码,来判断连接状态
        if (!FTPReply.isPositiveCompletion(reply)) {
            this.destory();
            // 连接错误
            throw new Exception("Can‘t Connect to :" + host);
        }
        // 登录
        boolean flag = client.login(this.username, this.password);
        if (flag == false) {
            this.destory();
            throw new Exception("Invalid user/password");
        }
        try {
            if (FTPReply.isPositiveCompletion(client.sendCommand("OPTS UTF8", "ON"))) {
                // 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码
                tranEncoding = "UTF-8";
                log.debug("FTP Server allow UTF8 encoding");
            }
        } catch (Exception e) {
            log.error("ftp server opts utf8 error,{}", e.getMessage());
        }
        log.info("use encoding {}", tranEncoding);
        client.setControlEncoding(tranEncoding); // 中文支持
        // 设置传送模式
        if (isTextMode) {
            client.setFileType(FTP.ASCII_FILE_TYPE);
        } else {
            client.setFileType(FTP.BINARY_FILE_TYPE);
        }
        /*
         * PORT中文称为主动模式,工作的原理:
         * FTP客户端连接到FTP服务器的21端口,发送用户名和密码登录,登录成功后要list列表或者读取数据时,
         * 客户端随机开放一个端口(1024以上),发送 PORT命令到FTP服务器,告诉服务器客户端采用主动模式并开放端口;
         * FTP服务器收到PORT主动模式命令和端口号后,通过服务器的20端口和客户端开放的端口连接,发送数据.
         * 主动模式需要客户端必须开放端口给服务器,很多客户端都是在防火墙内,开放端口给FTP服务器访问比较困难。
         */
        // client.enterLocalActiveMode(); //主动模式
        /*
         * PASV是Passive的缩写,中文成为被动模式.
         * 工作原理:FTP客户端连接到FTP服务器的21端口,发送用户名和密码登录,登录成功后要list列表或者读取数据时,
         * 发送PASV命令到FTP服务器, 服务器在本地随机开放一个端口(1024以上),然后把开放的端口告诉客户端,
         * 客户端再连接到服务器开放的端口进行数据传输. 被动模式只需要服务器端开放端口给客户端连接就行了。
         */
        client.enterLocalPassiveMode();
        // client.setUseEPSVwithIPv4(useEpsvWithIPv4);
        log.debug("==========初始化FTP连接成功===========");
    }

    public void destory() {
        if (client == null) {
            return;
        }
        try {
            client.logout();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            client.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
        }
        client = null;
    }

    public void changeRemoteDir(String newPath) throws RuntimeException {
        // 切换路径[相对路径和绝对路径都可]
        if (StringUtils.isBlank(newPath)) {
            return;
        }
        try {
            boolean flag = client.changeWorkingDirectory(new String(newPath.getBytes(tranEncoding), "ISO-8859-1"));
            log.debug("change working directory to {}, status:{}", newPath, flag);
        } catch (IOException e) {
            throw new RuntimeException("切换路径失败:" + newPath + "; " + e.getMessage());
        }
    }

    /**
     * 下载文件
     */
    public void download(String remoteFile, String localOutFile) throws RuntimeException {
        FileOutputStream outstream = null;
        // 下载文件
        try {
            log.debug("开始下载文件 {}", remoteFile);
            outstream = new FileOutputStream(new File(localOutFile));
            /*
             * 这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据. 因为ftp
             * server可能每次开启不同的端口来传输数据,但是在linux上,由于安全限制,可能某些端口没有开启,所以就出现阻塞
             */
            client.enterLocalPassiveMode();
            client.setFileType(FTP.BINARY_FILE_TYPE);
            /*
             * FTP协议里面,规定文件名编码为iso-8859-1,所以目录名或文件名需要转码 retrieveFile的第一个参数需要是
             * ISO-8859-1 编码
             */
            client.retrieveFile(new String(remoteFile.getBytes(tranEncoding), "ISO-8859-1"), outstream);
        } catch (IOException e) {
            throw new RuntimeException("下载文件失败:" + remoteFile + "; " + e.getMessage());
        } finally {
            if (outstream != null) {
                try {
                    outstream.flush();
                    outstream.close();
                } catch (IOException e) {
                }
            }
        }
        log.debug("下载文件 {} 完成", remoteFile);
    }
}

原文地址:http://blog.51cto.com/dengshuangfu/2130277

时间: 2024-08-28 00:29:47

使用commons-net来下载文件(仅做记录)的相关文章

python迁移邮件<仅做记录>

<脚本之初的原因是需要做邮件平移,并且已读,未读的状态一致.所以做了这个脚本> #!/usr/bin/python # -*- coding: utf-8 -*- #Filename: testemail.py import sys import os import imaplib import time import re import cPickle as p command=("status","qianyi","help")

微信无法下载文件如何做提示跳转到浏览器

需求分析 目前的APP基本都支持二维码扫描下载.由于微信现在是主流的聊天软件,90%的用户都是通过微信分享APP的,再从分享的链接下载apk/ios包.故用户通常使用微信打开链接或扫描二维码前往下载页,这是刚需. 在我们做营销活动或推广宣传的时候,容易遇到域名被封,无法跳转app下载等情况.这时需要微信跳转外部浏览器打开页面的功能,对于微信默认可以通过点击右上角的更多符号选择"在浏览器中打开".但是对于很多用户而言并不知道这样的实现,所以需要在代码中进行相关操作.目前ios只能通过遮罩

学习咏南BLOG的datasanp 用流下载文件,同时记录WINDOWS系统日志

服务器端: function TServerMethods1.getfile(filename: string): TStream; var    FilePath,DownFile:String;    FS:TFileStream;    log:TEventLogger ;//需要在USES里加上 Vcl.SvcMgr,才可以引用TEventLogger begin    FilePath:='d:\xe\';    DownFile:=FilePath+FileName;    log:

网站被攻击的请求,仅做记录

今天我们的网站被攻击,拦截请求中包含了以下内容.仅以为记. <input onfocus="document.write(String.fromCharCode(60,115,99,114,105,112,116,62,...60,47,115,99,114,105,112,116,62))" style="width:1px;height:1px;border:0;" autofocus="" value="loading...

阿里百川地址,趣拍iOS及andriod SDK--视频美颜,各种滤镜,仅做记录

阿里百川地址, http://baichuan.taobao.com/portal/doc?articleId=500 趣拍SDK http://www.qupai.me/sdk.html 版权声明:本文为博主原创文章,未经博主允许不得转载.

面试题:编写上传和下载文件测试用例

编写上传和下载文件测试用例 走火入魔系列之:上传|下载文件 一.题目: 如何编写上传和下载文件测试用例 1. 上传功能测试点 假如:我们要调试上传功能,前端代码为: <!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> <

Java 利用Apache Commons Net 实现 FTP文件上传下载

package woxingwosu; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Comparator;

org.apache.commons.net.ftp.FTPClient 下载文件提示Software caused connection abort: recv failed

今天在使用FTPClient下载文件时,登录成功了,但是提示下图所示的错误信息: 出现这个问题,本以为设置的读取文件目录不对,尝试修改多次无果.为了排除路径的问题,在firefox中安装了插件"FireFTP",连接上之后,可以正常下载,于是该问题排除. 后来在http://blog.csdn.net/wangjinwei6912/article/details/6603152 看到这位朋友的提示防火墙的问题,于是打开系统的防火墙,发现系统的防火墙都是开着的,如下图所示: 尝试把防火墙

java实现FTP下载文件

ftp上传下载文件,是遵照ftp协议上传下载文件的,本例仅以下载文件为例. 重要的方法解释: 1.FTP功能相关依赖路径:org.apache.commons.net.ftp.*: 2.ftp默认端口是21,如果非默认端口连接,需指定:ftp.connect(ftphostaddr, 22);//22为端口号 3.ftp.changeWorkingDirectory(ftppath) //实现切换目录 4.FTPFile[] fs = ftp.listFiles(); 获取指定目录下的文件列表