码迷,mamicode.com
首页 > 移动开发 > 详细

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

时间:2016-07-24 12:09:09      阅读:607      评论:0      收藏:0      [点我收藏+]

标签:

1、前言:

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

http开源库:之前开发的时候先是用到了http协议上传文件,删除文件等等,使用的开源库是AsyncHttpClient开源框架android-async-http。当时我应用的场景也是需要从服务器下载文件,上传文件,以及删除文件。下载文件,上传文件我用了android-async-http这个。然后下载是用了使用HttpURLConnection断点续传下载文件。就是组合起来用吧。详细连接:android 使用AsyncHttpClient框架上传文件以及使用HttpURLConnection下载文件

ftp的简单介绍:FTP是File Transportation Protocol(文件传输协议)的缩写。目前在网络上,如果你想把文件和其他人共享。最方便的办法莫过于将文件放FTP服务器上,然后其他人通过FTP客户端程序来下载所需要的文件。如同其他的很多通讯协议,FTP通讯协议也采用客户机 / 服务器(Client / Server )架构。用户可以通过各种不同的FTP客户端程序,借助FTP协议,来连接FTP服务器,以上传或者下载文件。一般是需要ip,端口,用户名,以及密码。

http的简单介绍:HTTP则是Hyper Text Transportation Protocol(超文本传输协议)的缩写。HTTP是一种为了将位于全球各个地方的Web服务器中的内容发送给不特定多数用户而制订的协议。也就是说,可以把HTTP看作是旨在向不特定多数的用户“发放”文件的协议。 HTTP使用于从服务器读取Web页面内容。Web浏览器下载Web服务器中的HTML文件及图像文件等,并临时保存在个人电脑硬盘及内存中以供显示。 使用HTTP下载软件等内容时的不同之处只是在于是否以Web浏览器显示的方式保存,还是以不显示的方式保存而已。结构则完全相同。因此,只要指定文件,任何人都可以进行下载。 

我之前开发时候,是服务器那边开发人员,定义好接口以及接口需要携带的参数。我根据接口进行开发,我根据接口实现了用户的登录,注册,获取验证。以及后面的上传文件,删除服务器文件等等。需要参数看服务其那边怎么定义接口。

这里说一下TCP/IP连接:实际上socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API), 通过Socket,我们才能使用TCP/IP协议。TCP协议对应于传输层。在网络传输也是经常用到一块。socket连接开源库我就没用过。一般都是自已写就可以。如果有好用的,记得评论留下地址。

2、再次封装的CustomApacheFTPManage

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
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;

public class CustomApacheFTPManage {
	
	public static String hostName = "";
	public static int serverPort = 1200;
	public static String userName = ""; 
	public static String password = "";
	private static FTPClient ftpClient = null;
	
	public static final String FTP_CONNECT_SUCCESSS = "FTP_CONNECT_SUCCESSS";
	public static final String FTP_CONNECT_FAIL = "FTP_CONNECT_FAIL";
	public static final String FTP_DISCONNECT_SUCCESS = "FTP_DISCONNECT_SUCCESS";
	public static final String FTP_FILE_NOTEXISTS = "FTP_FILE_NOTEXISTS";
	
	public static final String FTP_UPLOAD_SUCCESS = "FTP_UPLOAD_SUCCESS";
	public static final String FTP_UPLOAD_FAIL = "FTP_UPLOAD_FAIL";
	public static final String FTP_UPLOAD_LOADING = "FTP_UPLOAD_LOADING";

	public static final String FTP_DOWN_LOADING = "FTP_DOWN_LOADING";
	public static final String FTP_DOWN_SUCCESS = "FTP_DOWN_SUCCESS";
	public static final String FTP_DOWN_FAIL = "FTP_DOWN_FAIL";
	
	public static final String FTP_DELETEFILE_SUCCESS = "FTP_DELETEFILE_SUCCESS";
	public static final String FTP_DELETEFILE_FAIL = "FTP_DELETEFILE_FAIL";

	//用于单例模式
	public static CustomApacheFTPManage mCustomFTPManage = null;

	//单例模式获取实例
	public static CustomApacheFTPManage GetInstance() {
		if (mCustomFTPManage == null || ftpClient == null ) {
			mCustomFTPManage = new CustomApacheFTPManage();
			ftpClient = new FTPClient();
		}
		return mCustomFTPManage;
	}
	
	public CustomApacheFTPManage(){
	
	}
	
	public void setParameter(String strhostName,int nserverPort ,String struserName,String strpassword) {
		hostName = strhostName;
		serverPort = nserverPort;
		userName = struserName;
		password = strpassword;
		
	}

	// -------------------------------------------------------文件上传方法------------------------------------------------

	/**
	 * 上传单个文件.
	 * 
	 * @param localFile
	 *            本地文件
	 * @param remotePath
	 *            FTP目录
	 * @param listener
	 *            监听器
	 * @throws IOException
	 */
	public void uploadSingleFile(File singleFile, String remotePath,CurrentTipListener listener) throws IOException {

		// 上传之前初始化
		this.uploadBeforeOperate(remotePath, listener);

		boolean flag;
		flag = uploadingSingle(singleFile, listener);
		// 上传完成之后关闭连接
		this.uploadAfterOperate(listener);
	}

	/**
	 * 上传多个文件.
	 * 
	 * @param localFile
	 *            本地文件
	 * @param remotePath
	 *            FTP目录
	 * @param listener
	 *            监听器
	 * @throws IOException
	 */
	public void uploadMultiFile(LinkedList<File> fileList, String remotePath,CurrentTipListener listener) throws IOException {

		// 上传之前初始化
		if (uploadBeforeOperate(remotePath, listener)) {
			boolean flag;

			int n = 0;
			for (File singleFile : fileList) {
				flag = uploadingSingle(singleFile, listener);
				if (flag) {
					n ++;
				if (n == fileList.size()) 
					listener.onCurrentTipCallBack(FTP_UPLOAD_SUCCESS);
				} else {
					listener.onCurrentTipCallBack(FTP_UPLOAD_FAIL);
				}
			}

			// 上传完成之后关闭连接
			this.uploadAfterOperate(listener);
		};
	}

	/**
	 * 上传单个文件.
	 * 
	 * @param localFile
	 *            本地文件
	 * @return true上传成功, false上传失败
	 * @throws IOException
	 */
	private boolean uploadingSingle(File localFile,CurrentTipListener listener) throws IOException {
		boolean flag = true;
		// 不带进度条的方式
		 // 创建输入流
		 InputStream inputStream = new FileInputStream(localFile);
		 // 上传单个文件
		 flag = ftpClient.storeFile(localFile.getName(), inputStream);
		 // 关闭文件流
		 inputStream.close();

		// 带有进度的方式
//		BufferedInputStream buffIn = new BufferedInputStream(
//				new FileInputStream(localFile));
//		ProgressInputStream progressInput = new ProgressInputStream(buffIn,
//				listener, localFile);
//		flag = ftpClient.storeFile(localFile.getName(), progressInput);
//		buffIn.close();

		return flag;
	}
	
	/**
	 * 上传文件之前初始化相关参数
	 * 
	 * @param remotePath
	 *            FTP目录
	 * @param listener
	 *            监听器
	 * @throws IOException
	 */
	private boolean uploadBeforeOperate(String remotePath,CurrentTipListener listener) throws IOException {

		// 打开FTP服务
		try {
			this.openConnect();
			listener.onCurrentTipCallBack(FTP_CONNECT_SUCCESSS);
		} catch (IOException e1) {
			e1.printStackTrace();
			listener.onCurrentTipCallBack(FTP_CONNECT_FAIL);
			return false;
		}

		// 设置模式
		ftpClient.setFileTransferMode(org.apache.commons.net.ftp.FTP.STREAM_TRANSFER_MODE);
		// FTP下创建文件夹
		ftpClient.makeDirectory(remotePath);
		// 改变FTP目录
		ftpClient.changeWorkingDirectory(remotePath);
		return true;
	}

	/**
	 * 上传完成之后关闭连接
	 * 
	 * @param listener
	 * @throws IOException
	 */
	private void uploadAfterOperate(CurrentTipListener listener)throws IOException {
		this.closeConnect();
	}

	// -------------------------------------------------------文件下载方法------------------------------------------------

	/**
	 * 下载单个文件,可实现断点下载.
	 * 
	 * @param serverPath
	 *            Ftp目录及文件路径
	 * @param localPath
	 *            本地目录
	 * @param fileName       
	 *            下载之后的文件名称
	 * @param listener
	 *            监听器
	 * @throws IOException
	 */
	public void downloadSingleFile(String serverPath, String localPath, String fileName, DownLoadProgressListener listener)
			throws Exception {

		// 打开FTP服务
		try {
			this.openConnect();
			listener.onDownLoadProgress(FTP_CONNECT_SUCCESSS, 0, null);
		} catch (IOException e1) {
			e1.printStackTrace();
			listener.onDownLoadProgress(FTP_CONNECT_FAIL, 0, null);
			return;
		}

		// 先判断服务器文件是否存在
		FTPFile[] files = ftpClient.listFiles(serverPath);
		if (files.length == 0) {
			listener.onDownLoadProgress(FTP_FILE_NOTEXISTS, 0, null);
			return;
		}

		//创建本地文件夹
		File mkFile = new File(localPath);
		if (!mkFile.exists()) {
			mkFile.mkdirs();
		}

		localPath = localPath + fileName;
		// 接着判断下载的文件是否能断点下载
		long serverSize = files[0].getSize(); // 获取远程文件的长度
		File localFile = new File(localPath);
		long localSize = 0;
		if (localFile.exists()) {
			localSize = localFile.length(); // 如果本地文件存在,获取本地文件的长度
			if (localSize >= serverSize) {
				File file = new File(localPath);
				file.delete();
			}
		}
		
		// 进度
		long step = serverSize / 100;
		long process = 0;
		long currentSize = 0;
		// 开始准备下载文件
		OutputStream out = new FileOutputStream(localFile, true);
		ftpClient.setRestartOffset(localSize);
		InputStream input = ftpClient.retrieveFileStream(serverPath);
		byte[] b = new byte[1024];
		int length = 0;
		while ((length = input.read(b)) != -1) {
			out.write(b, 0, length);
			currentSize = currentSize + length;
			if (currentSize / step != process) {
				process = currentSize / step;
				if (process % 5 == 0) {  //每隔%5的进度返回一次
					listener.onDownLoadProgress(FTP_DOWN_LOADING, process, null);
				}
			}
		}
		out.flush();
		out.close();
		input.close();
		
		// 此方法是来确保流处理完毕,如果没有此方法,可能会造成现程序死掉
		if (ftpClient.completePendingCommand()) {
			listener.onDownLoadProgress(FTP_DOWN_SUCCESS, 0, new File(localPath));
		} else {
			listener.onDownLoadProgress(FTP_DOWN_FAIL, 0, null);
		}

		// 下载完成之后关闭连接
		this.closeConnect();
		listener.onDownLoadProgress(FTP_DISCONNECT_SUCCESS, 0, null);

		return;
	}

	// -------------------------------------------------------文件删除方法------------------------------------------------

	/**
	 * 删除Ftp下的文件.
	 * 
	 * @param serverPath
	 *            Ftp目录及文件路径
	 * @param listener
	 *            监听器
	 * @throws IOException
	 */
	public void deleteSingleFile(String serverPath, DeleteFileProgressListener listener)
			throws Exception {

		// 打开FTP服务
		try {
			this.openConnect();
			listener.onDeleteProgress(FTP_CONNECT_SUCCESSS);
		} catch (IOException e1) {
			e1.printStackTrace();
			listener.onDeleteProgress(FTP_CONNECT_FAIL);
			return;
		}

		// 先判断服务器文件是否存在
		FTPFile[] files = ftpClient.listFiles(serverPath);
		if (files.length == 0) {
			listener.onDeleteProgress(FTP_FILE_NOTEXISTS);
			return;
		}
		
		//进行删除操作
		boolean flag = true;
		flag = ftpClient.deleteFile(serverPath);
		if (flag) {
			listener.onDeleteProgress(FTP_DELETEFILE_SUCCESS);
		} else {
			listener.onDeleteProgress(FTP_DELETEFILE_FAIL);
		}
		
		// 删除完成之后关闭连接
		this.closeConnect();
		listener.onDeleteProgress(FTP_DISCONNECT_SUCCESS);
		
		return;
	}

	// -------------------------------------------------------打开关闭连接------------------------------------------------

	/**
	 * 打开FTP服务.
	 * 
	 * @throws IOException
	 */
	public void openConnect() throws IOException {
		// 中文转码
		ftpClient.setControlEncoding("UTF-8");
		int reply; // 服务器响应值
		// 连接至服务器
		ftpClient.connect(hostName, serverPort);
		// 获取响应值
		reply = ftpClient.getReplyCode();
		if (!FTPReply.isPositiveCompletion(reply)) {
			// 断开连接
			ftpClient.disconnect();
			throw new IOException("connect fail: " + reply);
		}
		// 登录到服务器
		ftpClient.login(userName, password);
		// 获取响应值
		reply = ftpClient.getReplyCode();
		if (!FTPReply.isPositiveCompletion(reply)) {
			// 断开连接
			ftpClient.disconnect();
			throw new IOException("connect fail: " + reply);
		} else {
			// 获取登录信息
			FTPClientConfig config = new FTPClientConfig(ftpClient.getSystemType().split(" ")[0]);
			config.setServerLanguageCode("zh");
			ftpClient.configure(config);
			// 使用被动模式设为默认
			ftpClient.enterLocalPassiveMode();
			// 二进制文件支持
			ftpClient.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
		}
	}

	/**
	 * 关闭FTP服务.
	 * 
	 * @throws IOException
	 */
	public void closeConnect() throws IOException {
		if (ftpClient != null) {
			// 退出FTP
			ftpClient.logout();
			// 断开连接
			ftpClient.disconnect();
		}
	}

	// ---------------------------------------------------上传、下载、删除监听---------------------------------------------
	
	/*
	 * 下载进度监听
	 */
	public interface DownLoadProgressListener {
		public void onDownLoadProgress(String currentStep, long downProcess, File file);
	}

	/*
	 * 文件删除监听
	 */
	public interface DeleteFileProgressListener {
		public void onDeleteProgress(String currentStep);
	}
	
	public interface CurrentTipListener {
		public void onCurrentTipCallBack(String currentStep);
	}
	
	//上传文件准备
	public void onUploadSFile(final LinkedList<File> upload,final CurrentTipListener listener) {
		//ftp服务器需要新建的文件夹名称
		final String strFTPpath = "/" + getCurrentDataTime("yyyyMMddHHmmss");
		new Thread(new Runnable() {			
			@Override
			public void run() {
                try {
                	//需要上传的文件upload
                   	uploadMultiFile(upload, strFTPpath, listener);
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			}
		}).start();
	} 

	public String getCurrentDataTime(String string) {  
	    Date date = new Date(System.currentTimeMillis());  
	    SimpleDateFormat sdformat = new SimpleDateFormat(string);// 24小时制  
	    String LgTime = sdformat.format(date);  
	    return LgTime;  
	}  
}

记得加入使用网络的权限。

不同的连接,有不同的传输协议。

本文博客涉及的代码:点击下载

3、参考网址

android与服务器通信方式的区别 

Android系列之网络(一)----使用HttpClient发送HTTP请求(通过get方法获取数据)
Android中FTP上传、下载(含进度)



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

标签:

原文地址:http://blog.csdn.net/qq_16064871/article/details/52012924

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!