版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/birdsaction/article/details/36379201

在Android使用ftp下载资源 能够使用ftp4j组件,还能够用apache common net里面的ftp组件,这2个组件我都用过。

个人感觉Apache common net里面的组件比較好用一些,以下是一个实例。

项目中对ftp的使用进行了封装,加入了回调函数已经断点续传的方法。

 

 

FTPCfg 用来存储ftp地址。password等信息的.

FTPClientProxy 仅仅是个代理而已,里面主要封装了common ftp api

IRetrieveListener做回调用的。比方用于是否下载完毕,是否有错误等 能够通知到UI层

FTPManager 调用主入口

 

/**
* bufferSize default is 1024*4
*
* @author gaofeng
* 2014-6-18
*/
public class FTPCfg { public FTPCfg() {
} public int port;
public int bufferSize = 1024 * 4;
public String address;
public String user;
public String pass; }

 

 

 

/**
*
*/
package com.birds.mobile.net.ftp; import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import android.util.Log;
/**
* @author gaofeng 2014-6-18
*/
public class FTPClientProxy { FTPClient ftpClient = new FTPClient();
FTPCfg config; protected FTPClientProxy(FTPCfg cfg) {
this.config = cfg;
} public FTPCfg getConfig() {
return config;
} public boolean connect() {
try {
FTPClientConfig ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
ftpClientConfig.setLenientFutureDates(true);
ftpClient.configure(ftpClientConfig);
ftpClient.connect(config.address, config.port);
int reply = this.ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
return false;
}
return true;
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
} public boolean login() {
if (!ftpClient.isConnected()) {
return false;
}
try {
boolean b = ftpClient.login(config.user, config.pass);
if (!b) {
return false;
}
ftpClient.setFileType(FTPClient.FILE_STRUCTURE);
ftpClient.enterLocalPassiveMode(); // very important
// ftpClient.enterLocalActiveMode();
// ftpClient.enterRemotePassiveMode();
// ftpClient.enterRemoteActiveMode(InetAddress.getByName(config.address), config.port);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
return b;
} catch (IOException e) {
e.printStackTrace();
}
return false;
} public FTPFile[] getFTPFiles(String remoteDir) {
try {
return ftpClient.listFiles(remoteDir);
} catch (IOException e) {
e.printStackTrace();
}
return null;
} public FTPFile getFTPFile(String remotePath) {
try {
Log.d("","getFTPFile.........." + remotePath);
FTPFile f = ftpClient.mlistFile(remotePath);
return f;
} catch (IOException e) {
e.printStackTrace();
}
Log.d("","getFTPFile null..........");
return null;
} public InputStream getRemoteFileStream(String remotePath) {
InputStream ios;
try {
ios = ftpClient.retrieveFileStream(remotePath);
return ios;
} catch (IOException e) {
e.printStackTrace();
}
return null;
} public void close() {
if (ftpClient.isConnected()) {
try {
ftpClient.logout();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
} public void setRestartOffset(long len) {
ftpClient.setRestartOffset(len);//断点续传的position
} public boolean isDone() {
try {
return ftpClient.completePendingCommand();
} catch (IOException e) {
e.printStackTrace();
}
return false;
} }

ftp有各种模式。这地方easy出错,导致无法获取到FTP上面的资源。

LocalPassiveMode。LocalActiveMode
就是主动模式和被动模式

要依据FTP所在server的网络来设置,须要自己測试一下。

 

 

 

/**
*
*/
package com.birds.mobile.net.ftp; import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream; import org.apache.commons.net.ftp.FTPFile; import android.util.Log; /**
* @author gaofeng 2014-6-18
*/
public class FTPManager { FTPClientProxy ftpProxy;
IRetrieveListener listener;
volatile boolean isLogin = false;
volatile boolean stopDownload = false; protected FTPManager(){ } public FTPManager(FTPCfg cfg) {
ftpProxy = new FTPClientProxy(cfg);
} /**
* track listener for FTP downloading
* @param listener
*/
public void setListener(IRetrieveListener listener) {
this.listener = listener;
} /**
* stop download task if you set true
* @param stopDownload
*/
public void setStopDownload(boolean stopDownload) {
this.stopDownload = stopDownload;
} public FTPFile[] showListFile(String remoteDir) {
return ftpProxy.getFTPFiles(remoteDir);
} public boolean connectLogin() {
boolean ok = false;
if (ftpProxy.connect()) {
ok = ftpProxy.login();
}
isLogin = ok;
return ok;
} /**
*
* @param remoteDir of FTP
* @param name of file name under FTP Server's remote DIR.
* @return FTPFile
*/
public FTPFile getFileByName(String remoteDir, String name) {
FTPFile[] files = showListFile(remoteDir);
if (files != null) {
for (FTPFile f : files) {
if (name.equalsIgnoreCase(f.getName())) {
return f;
}
}
}
return null;
} public void download(String remotePath, String localPath, long offset) {
listener.onStart();
File f = new File(localPath);
byte[] buffer = new byte[ftpProxy.getConfig().bufferSize];
int len = -1;
long now = -1;
boolean append = false;
InputStream ins = null;
OutputStream ous = null;
try {
if (offset > 0) { //用于续传
ftpProxy.setRestartOffset(offset);
now = offset;
append = true;
}
Log.d("", "downloadFile:" + now + ";" + remotePath);
ins = ftpProxy.getRemoteFileStream(remotePath);
ous = new FileOutputStream(f, append);
Log.d("", "downloadFileRenew:" + ins);
while ((len = ins.read(buffer)) != -1) {
if (stopDownload) {
break;
}
ous.write(buffer, 0, len);
now = now + len;
listener.onTrack(now);//监控当前下载了多少字节。可用于显示到UI进度条中
}
if (stopDownload) {
listener.onCancel("");
} else {
if (ftpProxy.isDone()) {
listener.onDone();
} else {
listener.onError("File Download Error", ERROR.FILE_DOWNLOAD_ERROR);
}
} } catch (IOException e) {
e.printStackTrace();
listener.onError("File Download Error:" + e, ERROR.FILE_DOWNLOAD_ERROR);
} finally {
try {
ous.close();
ins.close();
} catch (Exception e2) {
}
}
} public void download(String remotePath, String localPath) {
download(remotePath, localPath, -1);
} public void close() {
ftpProxy.close();
} public static class ERROR { //自定义的一些错误代码
public static final int FILE_NO_FOUNT = 9001;
public static final int FILE_DOWNLOAD_ERROR = 9002;
public static final int LOGIN_ERROR = 9003;
public static final int CONNECT_ERROR = 9004;
}
}

 

 回调函数

public interface IRetrieveListener {
public void onStart();
public void onTrack(long nowOffset);
public void onError(Object obj, int type);
public void onCancel(Object obj);
public void onDone();
}

library用的是apache common net 3.3

 

測试代码放在附件里面。不是非常完好,但基本能够用。

http://download.csdn.net/detail/birdsaction/7580539

 

 

 

 

Android中使用Apache common ftp进行下载文件的更多相关文章

  1. 【FTP】C# System.Net.FtpClient库连接ftp服务器(下载文件)

    如果自己单枪匹马写一个连接ftp服务器代码那是相当恐怖的(socket通信),有一个评价较高的dll库可以供我们使用. 那就是System.Net.FtpClient,链接地址:https://net ...

  2. (4)FTP服务器下载文件

    上一篇中,我们提到了怎么从FTP服务器下载文件.现在来具体讲述一下. 首先是路径配置.. 所以此处我们需要一个app.config来设置路径. <?xml version="1.0&q ...

  3. C#- FTP递归下载文件

    c# ftp递归下载文件,找来找去这个最好.(打断点,一小处foreach要改成for) /// <summary> /// ftp文件上传.下载操作类 /// </summary& ...

  4. Python之FTP多线程下载文件之分块多线程文件合并

    Python之FTP多线程下载文件之分块多线程文件合并 欢迎大家阅读Python之FTP多线程下载系列之二:Python之FTP多线程下载文件之分块多线程文件合并,本系列的第一篇:Python之FTP ...

  5. Python之FTP多线程下载文件之多线程分块下载文件

    Python之FTP多线程下载文件之多线程分块下载文件 Python中的ftplib模块用于对FTP的相关操作,常见的如下载,上传等.使用python从FTP下载较大的文件时,往往比较耗时,如何提高从 ...

  6. 如何在Linux中使用sFTP上传或下载文件与文件夹

    如何在Linux中使用sFTP上传或下载文件与文件夹 sFTP(安全文件传输程序)是一种安全的交互式文件传输程序,其工作方式与 FTP(文件传输协议)类似. 然而,sFTP 比 FTP 更安全;它通过 ...

  7. 通过cmd命令到ftp上下载文件

    通过cmd命令到ftp上下载文件 点击"开始"菜单.然后输入"cmd"点"enter"键,出现cmd命令执行框 2 输入"ftp& ...

  8. 访问FTP站点下载文件,提示“当前的安全设置不允许从该位置下载文件”的解决方案

    访问FTP站点下载文件,提示“当前的安全设置不允许从该位置下载文件”的解决方案: 打开客戶端浏览器--工具---internet-安全-自定义级别-选择到低到中低. 然后点受信任站点,把你要访问的站点 ...

  9. 26、android上跑apache的ftp服务

    一.为啥 在android设备跑ftp服务,在现场方便查看日志,目前就是这么用的. 二.前提: 从apache的官网下载依赖包:http://mina.apache.org/ftpserver-pro ...

随机推荐

  1. python 升级后正确安装 pip

    由于服务器的python 版本是2.6.6 , 为了使用 twisted 升级至 2.7.13 , 如果此时直接用 yum install python-pip 安装 pip, 则实际pip 会安装在 ...

  2. Django--创建

    软件开发架构: c/s架构 客户端 服务端 b/s架构 浏览器 服务端 本质:b/s架构也是c/s架构 HTTP协议 超文本传输协议:规定了客户端与服务端之间消息传输的格式 四个特性: 1.基于TCP ...

  3. 开始使用Apache弗林克和Mapr Streams

    Introduction MapR Ecosystem Package 2.0 (MEP) is coming with some new features related to MapR Strea ...

  4. http响应头信息

    HTTP 响应头信息 HTTP请求头提供了关于请求,响应或者其他的发送实体的信息. 在本章节中我们将具体来介绍HTTP响应头信息. 应答头 说明 Allow 服务器支持哪些请求方法(如GET.POST ...

  5. 2019阿里云开年Hi购季新用户分会场全攻略!

    2019阿里云云上Hi购季活动已经于2月25日正式开启,从已开放的活动页面来看,活动分为三个阶段: 2月25日-3月04日的活动报名阶段.3月04日-3月16日的新购满返+5折抢购阶段.3月16日-3 ...

  6. hdu 2444 The Accomodation of Students(二分匹配 匈牙利算法 邻接表实现)

    The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  7. SQL —— 存储过程

    一.什么是存储过程 预先存储好的SQL程序. 保存在SQL Server中(跟视图的存储方式一样) 通过名称和参数执行. 二.存储过程的优点 执行速度更快 允许模块化程序设计 提高系统安全性 减少网络 ...

  8. 我从HTML的meta中学到了什么

    meta meta中有这样几个常用属性:http-equiv,name,content,包括html5新增的charset. 注意:content属性用来存储meta信息的内容,所有的主流浏览器都支持 ...

  9. 洛谷3861八月月赛A题解

    链接 用f[i][j]表示乘积为i的,包含的最大数小于等于j时的方案总数 我们先考虑所用的数为1到n的情况 最后的答案就是f[n][n]-1 转移时考虑f[i][j]可以转移到的状态 显然f[i][j ...

  10. 【心有猛虎】react-lesson

    这个项目标识:构建一套适合 React.ES6 开发的脚手架 项目地址为:https://github.com/ZengTianShengZ/react-lesson 运行的是第一课,基本上可以当作是 ...