在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

更多相关文章

  1. 当复仇者联盟遇上Dagger2、RxJava和Retrofit的巧妙结合
  2. Unity与Android对比学习之生命周期方法
  3. 【定制Android系统】Android(安卓)7.1 默认的 USB 配置模式,默认
  4. Android(安卓)MVC模式
  5. [Android]新手入门:Intent的介绍和常见用法总结
  6. Android基本组件之图像视图等余下组件(自用)
  7. 四大组件之Activity小结
  8. [Android]Android(安卓)Activity 启动模式详解
  9. Android源码设计模式学习笔记-MVC,MVP架构模式

随机推荐

  1. How Android(安卓)Draws Views,Android如
  2. Android(安卓)Media Server - MediaPlaye
  3. Android开发-WebSocketWssDemo
  4. android学习小结4
  5. Android(安卓)Drawable工具类
  6. Android(安卓)获取手机的IMEI等设备信息
  7. android GPS JAVA应用程序编程-------获
  8. Android(安卓)终端上的开发工具
  9. Android(安卓)Bluetooth 文件接收路径修
  10. Android(安卓)Studio第六期 - 横向GridVi