標籤:
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))的縮寫。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) {// 退出FTPftpClient.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() {@Overridepublic 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區別分析