[Android中級]使用Commons-net-ftp來實現FTP上傳、下載的功能

來源:互聯網
上載者:User

標籤:android   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和使用者權限什麼的。


2.demo的結構,一如既往,紅框內的是重點。jar包可在Apache上下載(http://commons.apache.org/proper/commons-net/download_net.cgi)


3.主介面和原始碼



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() {@Overridepublic void handleMessage(Message msg) {if (msg.what == SHOW_DIALOG) {showProgressDialog(msg.obj == null ? "請等待..." : msg.obj.toString());} else if (msg.what == HIDE_DIALOG) {hideProgressDialog();}}};@Overrideprotected 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();}}@Overrideprotected void onDestroy() {super.onDestroy();new Thread() {@Overridepublic void run() {mFtpManager.close();}}.start();ToastUtil.cancel();}@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic void onTrack(long curPos) {Log.d(TAG, "--onTrack--" + curPos);}@Overridepublic void onStart() {Log.d(TAG, "--onStart--");mHandler.sendEmptyMessage(SHOW_DIALOG);}@Overridepublic void onError(int code, String msg) {Log.e(TAG, "download error:" + msg);mHandler.sendEmptyMessage(HIDE_DIALOG);ToastUtil.showShortToast(getApplicationContext(), "下載失敗",true);}@Overridepublic void onDone() {Log.i(TAG, "download success");mHandler.sendEmptyMessage(HIDE_DIALOG);ToastUtil.showShortToast(MainActivity.this, "下載成功",true);}@Overridepublic 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() {@Overridepublic 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() {@Overridepublic void onTrack(long curPos) {Log.d(TAG, "upload--onTrack--" + curPos);}@Overridepublic void onStart() {Log.d(TAG, "upload--onStart--");Message msg = mHandler.obtainMessage(SHOW_DIALOG);msg.obj = "正在上傳...";mHandler.sendMessage(msg);}@Overridepublic void onError(int code, String msg) {Log.e(TAG, "upload error:" + msg);mHandler.sendEmptyMessage(HIDE_DIALOG);ToastUtil.showShortToast(MainActivity.this, "上傳失敗",true);}@Overridepublic void onDone() {Log.i(TAG, "upload success");mHandler.sendEmptyMessage(HIDE_DIALOG);ToastUtil.showShortToast(MainActivity.this, "上傳成功",true);}@Overridepublic 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的話,請自行下載哦。

點擊這裡下載吧。






著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

[Android中級]使用Commons-net-ftp來實現FTP上傳、下載的功能

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.