[Android中级]使用Commons-net-ftp回实现FTP上传、下载的功能

[Android中级]使用Commons-net-ftp来实现FTP上传、下载的功能

   本文属于学习分享,如有雷同纯属巧合[Android中级]使用Commons-net-ftp回实现FTP上传、下载的功能

利用业余时间,学习一些有用的东西,如果手又有点贱的话,不妨自己也跟着敲起来[Android中级]使用Commons-net-ftp回实现FTP上传、下载的功能

在android上可以通过自带的ftp组件来完成各种功能,这次是因为项目中看到用了Commons-net-ftp的包完成的,所以就以此试试手。

首先,代码中有所参考借鉴了:Android中使用Apache common ftp进行下载文件 博文 

这次是分享关于在android上使用FTP协议(文件传输协议)进行文件的下载、上传的功能。我们可以先了解一下,FTP和HTTP一样都是Internet上广泛使用的协议,用来在两台计算机之间互相传送文件。相比于HTTP,FTP协议要复杂得多。复杂的原因,是因为FTP协议要用到两个TCP连接,一个是命令链路,用来在FTP客户端与服务器之间传递命令;另一个是数据链路,用来上传或下载数据。

1.为了测试FTP服务,本文中使用的是filezilla server 程序 模拟的。https://filezilla-project.org/  这里就不说怎么安装的了,简单就是设置ip和用户权限什么的。[Android中级]使用Commons-net-ftp回实现FTP上传、下载的功能


2.demo的结构,一如既往,红框内的是重点。jar包可在Apache上下载(http://commons.apache.org/proper/commons-net/download_net.cgi)

[Android中级]使用Commons-net-ftp回实现FTP上传、下载的功能

3.主界面和源代码

[Android中级]使用Commons-net-ftp回实现FTP上传、下载的功能


MainActivity.java         (代码很粗糙,但将就着看吧)

/**
 * ftp demo的主界面
 * @author jan
 *
 */
public class MainActivity extends Activity implements OnClickListener {
	private static final String TAG = "MainActivity";
	private static final int SHOW_DIALOG = 1000;
	private static final int HIDE_DIALOG = 1001;
	private Button mLoginButton;
	private EditText mUserEt;
	private EditText mPasswordEt;
	private Button mDownloadBtn;
	private Button mUploadBtn;

	private FTPManager mFtpManager;
	private InputMethodManager mImm;
	private ProgressDialog mProgressDialog;
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			if (msg.what == SHOW_DIALOG) {
				showProgressDialog(msg.obj == null ? "请等待..." : msg.obj
						.toString());
			} else if (msg.what == HIDE_DIALOG) {
				hideProgressDialog();
			}
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.main);
		mImm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		initView();
		FTPConfig config = new FTPConfig("192.168.1.29", 21);
		config.user = "jan";
		config.pwd = "123456";
		mUserEt.setText(config.user);
		mPasswordEt.setText(config.pwd);
		mFtpManager = FTPManager.getInstance(config);
	}

	private void initView() {
		mLoginButton = (Button) findViewById(R.id.login_button);
		mLoginButton.setOnClickListener(this);
		mUserEt = (EditText) findViewById(R.id.username_et);
		mPasswordEt = (EditText) findViewById(R.id.password_et);
		mDownloadBtn = (Button) findViewById(R.id.button1);
		mDownloadBtn.setOnClickListener(this);
		mUploadBtn = (Button) findViewById(R.id.button2);
		mUploadBtn.setOnClickListener(this);
	}

	private void showProgressDialog(String content) {
		if (mProgressDialog == null) {
			mProgressDialog = new ProgressDialog(this,
					ProgressDialog.STYLE_HORIZONTAL);
		}
		mProgressDialog.setTitle("提示信息");
		mProgressDialog.setMessage(content);
		mProgressDialog.setCancelable(false);
		mProgressDialog.show();
	}

	private void hideProgressDialog() {
		if (mProgressDialog != null) {
			mProgressDialog.dismiss();
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		new Thread() {
			@Override
			public void run() {
				mFtpManager.close();
			}
		}.start();
		ToastUtil.cancel();
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		// 连接和登陆测试
		case R.id.login_button:
			loginFtp();
			break;
		// 下载ftp上的指定文件
		case R.id.button1:
			downloadFile();
			break;
		// 上传android上的指定的文件到ftp服务器
		case R.id.button2:
			uoloadFile();
			break;
		}
	}

	/**
	 * 登陆功能测试
	 */
	private void loginFtp() {
		mImm.hideSoftInputFromWindow(mPasswordEt.getWindowToken(), 0);
		if (StringUtils.isEmpty(mUserEt.getText().toString().trim())) {
			ToastUtil.showShortToast(this, "账号不能为空");
			return;
		}
		if (StringUtils.isEmpty(mPasswordEt.getText().toString().trim())) {
			ToastUtil.showShortToast(this, "密码不能为空");
			return;
		}
		new Thread() {
			@Override
			public void run() {
				Log.d(TAG, "start login!");
				if (mFtpManager.connectFTPServer()) {
					Log.d(TAG, "connectFTPServer  = true");
					//查看远程FTP上的文件
					FTPFile[] files = mFtpManager.getFTPFiles();
					Log.i(TAG, "files.size="+files.length);
					for(FTPFile f:files){
						Log.i(TAG, "file:"+f.getName());
					}
					ToastUtil.showShortToast(MainActivity.this, "连接ftp成功", true);
				}else{
					Log.d(TAG, "connectFTPServer  = false");
				}
			}
		}.start();
	}
	/**
	 * 获取一个下载存放文件的目录
	 * @return
	 */
	public String getSDPath() {
		File sdDir = null;
		boolean sdCardExist = Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
		if (sdCardExist) {
			sdDir = Environment.getExternalStorageDirectory();// 获取跟目录
		}
		return sdDir.toString();
	}

	/**
	 * 下载功能的测试
	 */
	private void downloadFile() {
		new Thread() {
			@Override
			public void run() {
				String localPath = getSDPath();
				if (!StringUtils.isEmpty(localPath)) {
					localPath = localPath + "/ftp_demo.log";
				} else {
					localPath = getApplicationContext().getFilesDir()
							.getAbsolutePath() + "/ftp_demo.log";
				}
				Log.d(TAG, "localPath=" + localPath);
				mFtpManager.setRetrieveListener(new IRetrieveListener() {
					@Override
					public void onTrack(long curPos) {
						Log.d(TAG, "--onTrack--" + curPos);
					}

					@Override
					public void onStart() {
						Log.d(TAG, "--onStart--");
						mHandler.sendEmptyMessage(SHOW_DIALOG);
					}

					@Override
					public void onError(int code, String msg) {
						Log.e(TAG, "download error:" + msg);
						mHandler.sendEmptyMessage(HIDE_DIALOG);
						ToastUtil.showShortToast(getApplicationContext(), "下载失败",
								true);
					}

					@Override
					public void onDone() {
						Log.i(TAG, "download success");
						mHandler.sendEmptyMessage(HIDE_DIALOG);
						ToastUtil.showShortToast(MainActivity.this, "下载成功",
								true);
					}

					@Override
					public void onCancel() {
						Log.i(TAG, "download onCancel");
						mHandler.sendEmptyMessage(HIDE_DIALOG);
					}
				});
				mFtpManager.downLoadFile("/ftp_test.log", localPath);
			}
		}.start();
	}
	/**
	 * 上传操作
	 */
	private void uoloadFile() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				String localPath = getSDPath();
				if (!StringUtils.isEmpty(localPath)) {
					localPath = localPath + "/ftp_demo.log";
				} else {
					localPath = getApplicationContext().getFilesDir()
							.getAbsolutePath() + "/ftp_demo.log";
				}
				Log.d(TAG, "localPath=" + localPath);
				File file = new File(localPath);
				try {
					if (!file.exists()) {
						file.createNewFile();
					}
					FileOutputStream fos = new FileOutputStream(file, false);
					BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"));
					bw.write("FTP上传测试用例");
					bw.flush();
					bw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				mFtpManager.setRetrieveListener(new IRetrieveListener() {
					@Override
					public void onTrack(long curPos) {
						Log.d(TAG, "upload--onTrack--" + curPos);
					}

					@Override
					public void onStart() {
						Log.d(TAG, "upload--onStart--");
						Message msg = mHandler.obtainMessage(SHOW_DIALOG);
						msg.obj = "正在上传...";
						mHandler.sendMessage(msg);
					}

					@Override
					public void onError(int code, String msg) {
						Log.e(TAG, "upload error:" + msg);
						mHandler.sendEmptyMessage(HIDE_DIALOG);
						ToastUtil.showShortToast(MainActivity.this, "上传失败",
								true);
					}

					@Override
					public void onDone() {
						Log.i(TAG, "upload success");
						mHandler.sendEmptyMessage(HIDE_DIALOG);
						ToastUtil.showShortToast(MainActivity.this, "上传成功",true);
					}

					@Override
					public void onCancel() {
						Log.i(TAG, "upload onCancel");
						mHandler.sendEmptyMessage(HIDE_DIALOG);
					}
				});
				mFtpManager.uploadFile(localPath, "ftp_up.log");
			}
		}).start();
	}
}


4.FtpManager.java

package org.jan.ftp.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
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 org.apache.commons.net.ftp.FTPSClient;
import org.apache.commons.net.util.TrustManagerUtils;
import org.jan.ftp.demo.bean.FTPConfig;

import android.util.Log;

/**
 * FTP 客户端管理类
 * 
 * @author jan
 */
public class FTPManager {
	private static final String TAG = "FTPManager";
	private static FTPManager mFtpManager;
	private FTPClient mFtpClient;
	private FTPSClient mFtpsClient;
	private static FTPConfig mConfig;
	private IRetrieveListener retrieveListener;
	private boolean isFTPS = false;
	volatile boolean isLogin = false;
	volatile boolean isStopDownload = false;

	private FTPManager() {
		mFtpClient = new FTPClient();
		mFtpsClient = new FTPSClient(false);
		mFtpsClient.setTrustManager(TrustManagerUtils
				.getAcceptAllTrustManager());
	}

	public static FTPManager getInstance(FTPConfig cfg) {
		if (mFtpManager == null) {
			mFtpManager = new FTPManager();
		}
		mConfig = cfg;
		return mFtpManager;
	}

	public static FTPManager getInstance(String host, int port) {
		if (mFtpManager == null) {
			mFtpManager = new FTPManager();
		}
		mConfig = new FTPConfig(host, port);
		return mFtpManager;
	}

	public void setRetrieveListener(IRetrieveListener retrieveListener) {
		this.retrieveListener = retrieveListener;
	}

	/**
	 * 连接并登陆ftp服务
	 * 
	 * @return
	 */
	public boolean connectFTPServer() {
		try {
			FTPClientConfig ftpClientCfg = new FTPClientConfig(
					FTPClientConfig.SYST_UNIX);
			ftpClientCfg.setLenientFutureDates(true);
			mFtpClient.configure(ftpClientCfg);
			mFtpClient.setConnectTimeout(15000);
			mFtpClient.connect(mConfig.ipAdress, mConfig.port);
			login();
			int replyCode = mFtpClient.getReplyCode();
			if (!FTPReply.isPositiveCompletion(replyCode)) {
				mFtpClient.disconnect();
				return false;
			}
		} catch (SocketException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	/**
	 * 登陆ftp服务端
	 * @return
	 */
	public boolean login() {
		try {
			if (mFtpClient.isConnected()) {
				boolean isLogin = mFtpClient.login(mConfig.user, mConfig.pwd);
				if (!isLogin) {
					return false;
				}
				mFtpClient.setControlEncoding("GBK");
				mFtpClient.setFileType(FTPClient.FILE_STRUCTURE);
				mFtpClient.enterLocalActiveMode();
				// mFtpClient.enterRemotePassiveMode();
				// mFtpClient.enterRemoteActiveMode(
				// InetAddress.getByName(mConfig.ipAdress), mConfig.port);
				mFtpClient.setFileType(FTP.BINARY_FILE_TYPE);
				return isLogin;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}
	/**
	 * 退出并关闭本次连接
	 */
	public void close() {
		try {
			if (mFtpClient.isConnected()) {
				mFtpClient.logout();
			}
			mFtpClient.disconnect();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 下载FTP上的文件
	 * @param remoteFileName
	 * @param localFileName
	 * @param currentSize
	 */
	public void downLoadFile(String remoteFileName, String localFileName,
			long currentSize) {
		Log.i(TAG, "downloadFile fileName=" + remoteFileName + " currentSize="
				+ currentSize);
		if (retrieveListener != null) {
			retrieveListener.onStart();
		}
		byte[] buffer = new byte[mConfig.bufferSize];
		int len = -1;
		long now = -1;
		boolean append = false;
		if (mFtpClient != null) {
			InputStream ins = null;
			FileOutputStream fos = null;
			try {
				File localFile = new File(localFileName);
				if (currentSize > 0) {
					mFtpClient.setRestartOffset(currentSize);
					now = currentSize;
					append = true;
				}
				ins = getRemoteFileStream(remoteFileName);
				fos = new FileOutputStream(localFile, append);
				if (ins == null) {
					throw new FileNotFoundException("remote file is not exist");
				}
				while ((len = ins.read(buffer)) != -1) {
					if (isStopDownload) {
						break;
					}
					fos.write(buffer, 0, len);
					now += len;
					retrieveListener.onTrack(now);

				}
				if (isStopDownload) {
					retrieveListener.onCancel();
				} else {
					if (mFtpClient.completePendingCommand()) {
						retrieveListener.onDone();
					} else {
						retrieveListener.onError(ERROR.DOWNLOAD_ERROR,
								"download fail");
					}
				}
			} catch (FileNotFoundException e) {
				retrieveListener.onError(ERROR.FILE_NO_FOUNT, "download fail:"
						+ e);
			} catch (IOException e) {
				retrieveListener.onError(ERROR.IO_ERROR, "download fail:" + e);
			} finally {
				try {
					ins.close();
					fos.close();
				} catch (Exception e2) {
				}
			}
		}
	}
	/**
	 * 下载FTP服务器上的指定文件到本地
	 * @param remotePath
	 * @param localPath
	 */
	public void downLoadFile(String remotePath, String localPath) {
		downLoadFile(remotePath, localPath, -1);
	}

	private InputStream getRemoteFileStream(String remoteFilePath) {
		InputStream is = null;
		try {
			is = mFtpClient.retrieveFileStream(remoteFilePath);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return is;
	}
	/**
	 * 上传文件
	 * @param localPath 本地需要上传的文件路径(包括后缀名)
	 * @param workDirectory 上传ftp服务器上的指定文件目录
	 * @param desFileName 目标文件名
	 * @return
	 */
	public boolean uploadFile(String localPath, String workDirectory,
			String desFileName) {
		Log.i(TAG, "uploadFile localPath=" + localPath + " desFileName="
				+ desFileName);
		if (retrieveListener != null) {
			retrieveListener.onStart();
		}
		try {
			if (mFtpClient != null && mFtpClient.isConnected()) {
				// 设置存储路径
				mFtpClient.makeDirectory(workDirectory);
				mFtpClient.changeWorkingDirectory(workDirectory);
				mFtpClient.setBufferSize(1024);

				FileInputStream fis = new FileInputStream(localPath);
				boolean isUploadSuccess = mFtpClient
						.storeFile(desFileName, fis);
				if (isUploadSuccess) {
					if (retrieveListener != null) {
						retrieveListener.onDone();
					}
				} else {
					if (retrieveListener != null) {
						retrieveListener.onError(ERROR.UPLOAD_ERROR,
								"upload fail");
					}
				}
				fis.close();
				return isUploadSuccess;
			}
		} catch (IOException e) {
			e.printStackTrace();
			if (retrieveListener != null) {
				retrieveListener.onError(ERROR.IO_ERROR, "upload error:" + e);
			}
		}
		return false;
	}

	/**
	 * 上传文件到目的ftp服务端根目录下
	 * 
	 * @param localFileName
	 *            待上传的源文件
	 * @param remoteFileName
	 *            服务端的文件名称
	 * @return 上传成功的标识
	 */
	public boolean uploadFile(String localFileName, String remoteFileName) {
		return uploadFile(localFileName, "/", remoteFileName);
	}

	public FTPFile[] getFTPFiles() {
		try {
			if(!mFtpClient.isConnected()){
				return null;
			}
			mFtpClient.changeToParentDirectory();
			return mFtpClient.listFiles();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public boolean deleteFile(String pathname){
		try {
			return mFtpClient.deleteFile(pathname);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	public boolean createDirectory(String pathname){
		try {
			return mFtpClient.makeDirectory(pathname);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	public FTPFile[] getFTPFiles(String remoteDir) {
		try {
			if(!mFtpClient.isConnected()){
				return null;
			}
			return mFtpClient.listFiles(remoteDir);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public boolean isStopDownload() {
		return isStopDownload;
	}

	public void setStopDownload(boolean isStopDownload) {
		this.isStopDownload = isStopDownload;
	}

	public boolean isFTPS() {
		return isFTPS;
	}

	public void setFTPS(boolean isFTPS) {
		if (isFTPS) {
			mFtpClient = mFtpsClient;
		} else {
			mFtpClient = new FTPClient();
		}
		this.isFTPS = isFTPS;
	}

	public interface IRetrieveListener {
		public void onStart();

		public void onTrack(long curPos);

		public void onError(int errorCode, String errorMsg);

		public void onCancel();

		public void onDone();
	}

	public static class ERROR {
		public static final int FILE_NO_FOUNT = 4000;
		public static final int FILE_DOWNLOAD_ERROR = 4001;
		public static final int LOGIN_ERROR = 4002;
		public static final int CONNECT_ERROR = 4003;
		public static final int IO_ERROR = 4004;
		public static final int DOWNLOAD_ERROR = 4005;
		public static final int UPLOAD_ERROR = 4006;
	}
}


使用起来其实很简单吧!

如果需要demo的话,请自行下载哦。

点击这里下载吧。






版权声明:本文为博主原创文章,未经博主允许不得转载。