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

在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

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

时间: 2025-01-03 18:59:41

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

Android Apache common ftp开源库以及http区别分析

1.前言: ftp开源库:Apache common ftp开源库上传文件到局域网的ftp上吧.开源库是commons-net-2.2.jar.包名是这样的:org.apache.commons.net.ftp.FTPClient;用这个框架也能可以上传,下载以及删除ftp服务器的文件的.我也是参考网上大神例子迅速在项目中使用,现在趁机会总结一下,以及我自已在此基础上再次封装的ftp使用类. http开源库:之前开发的时候先是用到了http协议上传文件,删除文件等等,使用的开源库是AsyncHt

C# 实现访问FTP服务器下载文件,获取文件夹信息小记

最近因为要开发广告制作工具,自动生成广告流,需要获取第三方服务器上的文件资源,经过摸索,从这次经历中记录下. FtpWebRequest reqFtp; WebResponse response = null; //获取文件夹信息 reqFtp = (FtpWebRequest)WebRequest.Create(this.ftp);//ftp://IP:port/文件夹名1/文件夹名2/.../文件夹名 reqFtp.UseBinary = true; reqFtp.KeepAlive = f

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

如何在Linux中使用sFTP上传或下载文件与文件夹 sFTP(安全文件传输程序)是一种安全的交互式文件传输程序,其工作方式与 FTP(文件传输协议)类似. 然而,sFTP 比 FTP 更安全;它通过加密 SSH 传输处理所有操作.在本文中,我们将向你展示如何使用 sFTP 上传/下载整个目录(包括其子目录和子文件). 作者:Aaron Kili来源:Linux中国|2017-03-09 14:42 移动端 收藏 分享 51CTO诚邀您9月23号和秒拍/国美/美团元专家一起聊智能CDN的优化之路

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

通过cmd命令到ftp上下载文件 点击"开始"菜单.然后输入"cmd"点"enter"键,出现cmd命令执行框 2 输入"ftp"切换到到ftp下面.然后输入"open 服务器地址".点击回车键.会提示你输入用户名和密码. 3 登陆成功后.输入"cd"命令.会显示"远程目录",输入"dir"命令会显示目录下的文件,权限等相关信息.可以通过"

26、android上跑apache的ftp服务

一.为啥 在android设备跑ftp服务,在现场方便查看日志,目前就是这么用的. 二.前提: 从apache的官网下载依赖包:http://mina.apache.org/ftpserver-project/download_1.0.6.html 解压后如下: 在最右侧的jar包列表中,并不需要全部导入我们的工程,需要导入的包为: 记得把jar包添加到buildPath,同时在order and export选项选中上步添加的jar包 三.如何用: 1 package com.example.

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

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

Android中视频的上传和下载

send方法参数列表: 1. HttpRequest.HttpMethod method 请求方式 HttpRequest.HttpMethod.GET get方式 HttpRequest.HttpMethod.POST post方式 2.String url 请求网址 3.RequestParams params 参数对象,对象以键值对形式存储,自动拼接(没有参数,就使用三个参数的send方法) 对象创建: RequestParams params = new RequestParams();

C#实现开发windows服务实现自动从FTP服务器下载文件(自行设置分/时执行)

最近在做一个每天定点从FTP自动下载节目.xml并更新到数据库的功能.首先想到用 FileSystemWatcher来监控下载到某个目录中的文件是否发生改变,如果改变就执行相应的操作,然后用timer来设置隔多长时间来下载.后来又想想了.用windwos服务来实现吧. 效果图: 执行的Log日志: INFO-2016/5/24 0:30:07--日志内容为:0/30/7进行time触发 INFO-2016/5/24 1:30:07--日志内容为:1/30/7进行time触发 INFO-2016/

Linux shell ftp命令下载文件 根据文件日期

需求:ftp获取远程数据的文件,根据文件的创建时间点下载文件. 可以自行扩展根据文件的大小等其他需求. 知识点总结: 1.获取文件的时间: ls -lrt|awk '{print $6" "$7" "$8}' 时间内容: Sep  8 16:03 2.时间格式转换 date -d "Sep 8 16:03" +%Y%m%d%H%M 转换结果: 201709081603 3.指定文件名,正则匹配 pattern="${month}.*.d