最近一段時間,因為公司項目的需要,對HTTP協定以及FTP協定都有所了解,并且在基于網絡開放源代碼
基礎上,能夠完成項目的要求。今天給大家分享下,怎樣建立屬于我們自己的FTP伺服器以及FPT用戶端,同時
非常非常感謝這些開源軟體及其作者為IT行業做出的貢獻,最大程度上至少解放了我們這些IT碼農。且看正文。
本文主要内容:
1、FTP服務端部署---- 基于Android中SwiFTP開源軟體介紹;
2、FTP用戶端部署 --- 基于ftp4j開源jar包的用戶端開發 ;
3、使用步驟 --- 如何測試我們搭建的FTP可操作性。
本文所涉及到的知識、文檔、源代碼照舊會在文章末尾列出。歡迎大家一起學習。
一、 FTP服務端部署
SwiFTP開源軟體是為Android系統開發,也就是說我們可以将其源代碼嵌入到我們的項目中。當然,對其進行
一定改造還是必不可少的。這兒隻是從感官上對SwiFTP的運作效果圖進行一下說面,以便幫助大家有初步認識:
SwiFTP 資料資訊:
Google Download 介紹 : http://code.google.com/p/swiftp/downloads/list
GitHub 介紹 : https://github.com/ppareit/swiftp
Android版本SwiFTP截圖
界面其實很簡單,但是從設計角度分析,SwiFTP架構系統還是值得我們研究的,當然如果你想改造成
屬于自己的FTP伺服器(一般就是改改使用者名、密碼、PWD(起始工作目錄))等,那更得花時間去鑽研了。
二、 FTP用戶端部署
接下來,重點介紹我們的主角ftp4j開源jar包,該jar包就是開發我們FTP用戶端核心了。
ftp4j官網位址:http://www.sauronsoftware.it/projects/ftp4j/。對比與AndroidSDK而言,也就是ftp4j
SDK了,一切的一切(文檔、源代碼、示例)都可以在官網查詢 。想要了解的同學,至少得保證把首頁給整明白吧。
1、ftp4j概要
官網描述如下:
The ftp4j libraryimplementsa Java full-features FTP client. With ftp4j embedded in your
application you can : FTP site (directory listing included), create, delete, transfer files
(upload and download) , browse the remote FTP site (directory listing included), create, delete,
rename and move remote directories and files.
關于FTP連接配接主要有如下幾種方式:
The ftp4j library can connect the remote FTP server:
· Througha direct TCP/IPconnection. 一般就是直接連接配接了。
· Througha FTP proxy. FTP代理
· Tunnelling through a HTTPproxy. HTTP代理
· Througha SOCKS 4/4aproxy.
· Througha SOCKS 5 proxy.
· You can add support to otherproxies plugging your own connector, since the ftp4jconnection manager
architecture is modular.
2、主要類簡介
下面根據官網的描述,将該ftp4j庫的主要類簡單說明下:
FTPClient類
該類封裝了對FTPCommand的請求操作。例如:連接配接FTP伺服器、進行各種各樣的FTP操作(上傳、下載下傳、
删除、重命名檔案 等)。基本使用流程圖如下:
利用僞代碼描述如下:
[java] view plain copy print ?
- //1、登入至FTPp伺服器
- mFTPClient.connect(mFTPHost, mFTPPort);
- //2、請求授權
- mFTPClient.login(mFTPUser, mFTPPassword);
- //3、各種FTP操作
- mFTPClient.upload();
- mFTPClient.download();
- //4、斷開FTP連接配接
- mFTPClient.disconnect();
主要方法:
public java.lang.String [] connect(java.lang.String host, int port) throws java.lang.IllegalStateException,
java.io.IOException , FTPIllegalReplyException , FTPException
功能:與FTP伺服器主機建立連接配接 .
參數 :
host - FTP伺服器的主機名(host name) 或者 ip位址
port - FTP伺服器的監聽端口
傳回值 : The server welcome message ,FTP伺服器響應消息
抛出異常類型 : (略,參見後文)
public void login(java.lang.String username , java.lang.String password)
throws java.lang.IllegalStateException,
java.io.IOException, FTPIllegalReplyException, FTPException
功能:根據使用者名以及密碼登入FTP伺服器
參數:
username – 登入FTP伺服器的使用者名.
password - 登入FTP伺服器的 密碼
傳回值:(無)
抛出異常類型 : (略,參見後文)
public java.lang.String currentDirectory() throws java.lang.IllegalStateException, java.io.IOException,
FTPIllegalReplyException, FTPException
功能 :擷取FTP伺服器目前工作目錄。
傳回值:FTP伺服器目前工作目錄
抛出異常類型 : (略,參見後文)
public long fileSize(java.lang.String path)
功能:擷取指定檔案的大小。
參數:
path -- 指定檔案所在的路徑,可以是相對路徑或者是絕對路徑。
傳回值 : 指定檔案的大小,機關為byte.
抛出異常類型 : (略,參見後文)
public void deleteFile(java.lang.String path) throws java.lang.IllegalStateException, java.io.IOException,
FTPIllegalReplyException, FTPException
功能:删除指定檔案
參數:
path -- 指定檔案所在的路徑,可以使相對路徑或者是絕對路徑。
傳回值:(無)
抛出異常類型 : (略,參見後文)
public void deleteDirectory(java.lang.String path) throws java.lang.IllegalStateException,
java.io.IOException, FTPIllegalReplyException, FTPException
功能: 删除指定檔案夾
參數:
path -- 指定檔案所在的路徑,可以使相對路徑或者是絕對路徑。
傳回值:(無)
抛出異常類型 : (略,參見後文)
public FTPFile[] list() throws java.lang.IllegalStateException , java.io.IOException,
功能: 擷取目前工作目錄所有檔案資訊:檔案名、檔案大小、檔案類型(檔案或者檔案夾)。
傳回值: FTPFile[]數組對象 ---- 該檔案夾所對應的資訊
抛出異常類型 : (略,參見後文)
public java.lang.String[] listNames()
功能: 擷取目前工作目錄的所有檔案名。
傳回值:String[]類型 ----- 所有檔案名
抛出異常類型 : (略,參見後文)
public void upload(java.io.File file , FTPDataTransferListener listener) throws java.lang.IllegalStateException,
java.io.FileNotFoundException, java.io.IOException, FTPIllegalReplyException, FTPException,
FTPDataTransferException, FTPAbortedException
功能 :上傳檔案至FTP伺服器。該操作會阻塞目前線程,阻塞會在操作完成後解除。該方法可以通過調用
abortCurrentDataTransfer()方法去中斷。預設上傳的檔案目錄是目前工作目錄,通過currentDirectory()方法
可以獲得。注意:不支援上傳檔案夾。
參數:file -- 上傳檔案的File對象
listener -- 監聽器 (稍後介紹)
抛出異常類型 : (略,參見後文)
public void download(java.lang.String remoteFileName, java.io.File localFile,
FTPDataTransferListener listener)
throws java.lang.IllegalStateException, java.io.FileNotFoundException,
java.io.IOException, FTPIllegalReplyException, FTPException,
FTPDataTransferException, FTPAbortedException
功能:下載下傳某個檔案值指定路徑。該操作會阻塞目前線程,阻塞會在操作完成後解除。該方法可以通過調用
abortCurrentDataTransfer()方法去中斷。注意:不支援下載下傳檔案夾。
參數:
remoteFileName - 相對路徑(相對于目前目錄)時則是檔案名或者絕對路徑(例如:Linux中以”\”為字首)
localFile - 本地存放檔案的File對象。
listener - 監聽器 (稍後介紹)
抛出異常類型 : (略,參見後文)
public void abortCurrentDataTransfer(boolean sendAborCommand) throws java.io.IOException,
FTPIllegalReplyException
功能:如果存在任何正在進行的檔案操作(上傳/下載下傳),該方法會中斷它
參數
sendAborCommand -- true則代表中斷檔案操作,并且發送ABORT 指令給FTP伺服器
false 代表關閉中斷檔案操作,将不會發送任何消息給FTP伺服器。
抛出異常類型 : (略,參見後文)
FTPFile 類
該類封裝了FTP伺服器中檔案的資訊,即Model類。
常量字段:
檔案對應類型
public static final intTYPE_FILE 檔案
public static final intTYPE_DIRECTORY 檔案夾
public static final intTYPE_LINK 檔案引用
主要方法:
public java.util.Date getModifiedDate() 擷取檔案最後修改日期。
public int getType() 擷取檔案類型。
public long getSize() 擷取檔案大小 ,機關為byte。
FTPDataTransferListener Interface
該接口約定了檔案傳輸過程中的回調方法類型。我們可以實作該類去監聽每個具體的檔案操作過程。
回調接口有:
void started() 回調方法,表示已開始檔案傳輸。
void completed() 回調方法,表示檔案傳輸已完成。
void aborted() 回調方法,表示檔案傳輸已被中斷,可由abortCurrentDataTransfer()觸發。
void failed() 回調方法,表示檔案傳輸由于某種錯誤而失敗。
void transferred(int length) 回調方法,表示本次回調過程中已下載下傳/上傳的檔案位元組大小。
參數: length --本次回調過程中下載下傳/上傳的檔案位元組大小。
PS :我們可以累積length大小,以便獲得目前檔案已傳輸的位元組數。
異常種類:
ftp4j的自定義共有如下幾種,基本上每個FTP操作,都伴随着這些異常,是以,我們需要捕獲這些異常資訊。
FTPAbortedException
當檔案傳輸過程被顯示中斷(例如,調用abortCurrentDataTransfer()方法)時,抛出該異常。
FTPDataTransferException
在檔案傳輸過程中,發生任何I/O(例如,無法建立檔案流)錯誤,都會抛出該異常。
FTPException
封裝了FTP錯誤碼以及錯誤消息的異常類。PS:類似于HTTP錯誤碼以及錯誤消息
常用方法:
public int getCode() 擷取異常發生時,FTP的錯誤碼(錯誤碼字段值具體可見FTPCodes類)
public java.lang.String getMessage() 擷取異常發生時,FTP的錯誤消息。
FTPIllegalReplyException
當FTP伺服器以一種非正常的方式---違反了FTP協定的規則響應時,抛出該異常。
FTPListParseException
通過list()方法請求FTP服務時,如果此時FTP伺服器的傳回的消息不能被正确的解析時,都會抛出該異常。
通過對這些相關知識的學習,足矣利用ftp4j jar包完成我們簡易卻又充實的專屬我們自己的FTP用戶端了。
接下來,便開始我們的FTP用戶端的開發。
3、FTP用戶端開發
在功能需求上,開發一個FTP用戶端和開發一個檔案選擇器甚至檔案管理器基本上沒有任何差別,唯一的差別
隻在于資料來源不同,這個不同會導緻功能實踐上更多細節的差異,例如:異常的捕獲、斷點嘗試等。代碼方面
我就不再贅述了,對前面所介紹類的掌握和了解,應該No Problem了。主要說一下兩點:
①、由于Android4.0不允許在主線程上進行網絡操作,例如:Socket程式設計,我們的操作必須放在新的線程中。
同時為了減少建立線程的開銷,我們試用了線程池去執行每一個FTP操作。
②、試用FTPClient時,不允許上傳/下載下傳檔案夾,我也沒有針對這一方面進行更多的開發(具體實作過程大緻
為:對檔案夾裡的每個檔案皆進行上傳/下載下傳操作),有興趣的同學可以看看這篇文章<基于ftp4j的FTP用戶端工具>,
會提升對你對ftp4j的使用認知的。
我們的FTP用戶端主要功能為:
①、顯示特定目錄清單;
②、删除檔案以及檔案夾,下載下傳檔案;
③、上傳檔案。
主要代碼如下:
[java] view plain copy print ?
- public class FtpMainActivity extends Activity implements OnClickListener {
- private static String TAG = CopyOfFtpMainActivity.class.getName();
- private CmdFactory mCmdFactory;
- private FTPClient mFTPClient;
- private ExecutorService mThreadPool;
- @Override
- protected void onDestroy() {
- mDameonRunning = false ;
- Thread thread = new Thread(mCmdFactory.createCmdDisConnect()) ;
- thread.start();
- //等待連接配接中斷
- try {
- thread.join(2000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- mThreadPool.shutdownNow();
- super.onDestroy();
- }
- //put線程池中執行
- private void executeConnectRequest() {
- mThreadPool.execute(mCmdFactory.createCmdConnect());
- }
- private void executeDisConnectRequest() {
- mThreadPool.execute(mCmdFactory.createCmdDisConnect());
- }
- private void executePWDRequest() {
- mThreadPool.execute(mCmdFactory.createCmdPWD());
- }
- private void executeLISTRequest() {
- mThreadPool.execute(mCmdFactory.createCmdLIST());
- }
- //建立FtpCmd的工廠類
- public class CmdFactory {
- public FtpCmd createCmdConnect() {
- return new CmdConnect();
- }
- public FtpCmd createCmdDisConnect() {
- return new CmdDisConnect();
- }
- }
- //繼承了Runnable接口
- public abstract class FtpCmd implements Runnable {
- public abstract void run();
- }
- //連接配接指令
- public class CmdConnect extends FtpCmd {
- @Override
- public void run() {
- boolean errorAndRetry = false ; //根據不同的異常類型,是否重新捕獲
- try {
- String[] welcome = mFTPClient.connect(mFTPHost, mFTPPort);
- if (welcome != null) {
- for (String value : welcome) {
- logv("connect " + value);
- }
- }
- mFTPClient.login(mFTPUser, mFTPPassword);
- mHandler.sendEmptyMessage(MSG_CMD_CONNECT_OK);
- }catch (IllegalStateException illegalEx) {
- illegalEx.printStackTrace();
- errorAndRetry = true ;
- }catch (IOException ex) {
- ex.printStackTrace();
- errorAndRetry = true ;
- }catch (FTPIllegalReplyException e) {
- e.printStackTrace();
- }catch (FTPException e) {
- e.printStackTrace();
- errorAndRetry = true ;
- }
- if(errorAndRetry && mDameonRunning){
- mHandler.sendEmptyMessageDelayed(MSG_CMD_CONNECT_FAILED, 2000);
- }
- }
- }
- public class CmdDisConnect extends FtpCmd {
- @Override
- public void run() {
- if (mFTPClient != null) {
- try {
- mFTPClient.disconnect(true);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- }
- }
- }
- //下載下傳指令
- public class CmdDownLoad extends AsyncTask<Void, Integer, Boolean> {
- @Override
- protected Boolean doInBackground(Void... params) {
- try {
- String localPath = getParentRootPath() + File.separator
- + mFileList.get(mSelectedPosistion).getName();
- mFTPClient.download(
- mFileList.get(mSelectedPosistion).getName(),
- new File(localPath),
- new DownloadFTPDataTransferListener(mFileList.get(
- mSelectedPosistion).getSize()));
- } catch (Exception ex) {
- ex.printStackTrace();
- return false;
- }
- return true;
- }
- protected void onPostExecute(Boolean result) {
- toast(result ? "下載下傳成功" : "下載下傳失敗");
- progressDialog.dismiss();
- }
- }
- }
三,使用方法說明
前提條件, 確定兩台手機分别安裝FTP服務端,FTP用戶端 ,并且能連接配接上WIFI網絡。
第一步:運作FTP伺服器SwiFtp,輸入基本資訊(端口、使用者名、密碼),同時確定FTP伺服器成功開啟 。如圖:
配置FTP伺服器資訊 FTP伺服器狀态
第二步:運作FTP用戶端,填寫FTP驗證時的資料(即第一步輸入資訊)後,連接配接FTP伺服器即可。如圖:
最後,本文所涉及到的所有資料以及文章中示例的源代碼的下載下傳位址為:
http://download.csdn.net/detail/qinjuning/5034873
文章位址:http://blog.csdn.net/qinjuning/article/details/8545601