您的位置:首页 > 运维架构 > Apache

Android中使用Apache common ftp进行下载文件

2014-07-02 10:23 537 查看
在Android使用ftp下载资源 可以使用ftp4j组件,还可以用apache common net里面的ftp组件,这2个组件我都用过。

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

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



FTPCfg 用来存储ftp地址,密码等信息的.

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有各种模式,这地方容易出错,导致无法获取到FTP上面的资源。

LocalPassiveMode,LocalActiveMode

就是主动模式和被动模式

要根据FTP所在服务器的网络来设置,需要自己测试一下。

/**
*
*/
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: