Android中FTP上傳、下載的功能實(shí)現(xiàn)(含進(jìn)度)
Android中使用的FTP上傳、下載,含有進(jìn)度。
代碼部分主要分為三個文件:MainActivity,F(xiàn)TP,ProgressInputStream
1. MainActivity
package com.ftp;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import com.ftp.FTP.DeleteFileProgressListener;
import com.ftp.FTP.DownLoadProgressListener;
import com.ftp.FTP.UploadProgressListener;
import android.app.Activity;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
public static final String FTP_CONNECT_SUCCESSS = "ftp連接成功";
public static final String FTP_CONNECT_FAIL = "ftp連接失敗";
public static final String FTP_DISCONNECT_SUCCESS = "ftp斷開連接";
public static final String FTP_FILE_NOTEXISTS = "ftp上文件不存在";
public static final String FTP_UPLOAD_SUCCESS = "ftp文件上傳成功";
public static final String FTP_UPLOAD_FAIL = "ftp文件上傳失敗";
public static final String FTP_UPLOAD_LOADING = "ftp文件正在上傳";
public static final String FTP_DOWN_LOADING = "ftp文件正在下載";
public static final String FTP_DOWN_SUCCESS = "ftp文件下載成功";
public static final String FTP_DOWN_FAIL = "ftp文件下載失敗";
public static final String FTP_DELETEFILE_SUCCESS = "ftp文件刪除成功";
public static final String FTP_DELETEFILE_FAIL = "ftp文件刪除失敗";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initView();
}
private void initView() {
//上傳功能
//new FTP().uploadMultiFile為多文件上傳
//new FTP().uploadSingleFile為單文件上傳
Button buttonUpload = (Button) findViewById(R.id.button_upload);
buttonUpload.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
// 上傳
File file = new File("/mnt/sdcard/ftpTest.docx");
try {
//單文件上傳
new FTP().uploadSingleFile(file, "/fff",new UploadProgressListener(){
@Override
public void onUploadProgress(String currentStep,long uploadSize,File file) {
// TODO Auto-generated method stub
Log.d(TAG, currentStep);
if(currentStep.equals(MainActivity.FTP_UPLOAD_SUCCESS)){
Log.d(TAG, "-----shanchuan--successful");
} else if(currentStep.equals(MainActivity.FTP_UPLOAD_LOADING)){
long fize = file.length();
float num = (float)uploadSize / (float)fize;
int result = (int)(num * 100);
Log.d(TAG, "-----shangchuan---"+result + "%");
}
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
});
//下載功能
Button buttonDown = (Button)findViewById(R.id.button_down);
buttonDown.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
// 下載
try {
//單文件下載
new FTP().downloadSingleFile("/fff/ftpTest.docx","/mnt/sdcard/download/","ftpTest.docx",new DownLoadProgressListener(){
@Override
public void onDownLoadProgress(String currentStep, long downProcess, File file) {
Log.d(TAG, currentStep);
if(currentStep.equals(MainActivity.FTP_DOWN_SUCCESS)){
Log.d(TAG, "-----xiazai--successful");
} else if(currentStep.equals(MainActivity.FTP_DOWN_LOADING)){
Log.d(TAG, "-----xiazai---"+downProcess + "%");
}
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
});
//刪除功能
Button buttonDelete = (Button)findViewById(R.id.button_delete);
buttonDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
// 刪除
try {
new FTP().deleteSingleFile("/fff/ftpTest.docx",new DeleteFileProgressListener(){
@Override
public void onDeleteProgress(String currentStep) {
Log.d(TAG, currentStep);
if(currentStep.equals(MainActivity.FTP_DELETEFILE_SUCCESS)){
Log.d(TAG, "-----shanchu--success");
} else if(currentStep.equals(MainActivity.FTP_DELETEFILE_FAIL)){
Log.d(TAG, "-----shanchu--fail");
}
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
});
}
}
2. FTP
package com.ftp;
import java.io.BufferedInputStream;
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.util.Date;
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 FTP {
/**
* 服務(wù)器名.
*/
private String hostName;
/**
* 端口號
*/
private int serverPort;
/**
* 用戶名.
*/
private String userName;
/**
* 密碼.
*/
private String password;
/**
* FTP連接.
*/
private FTPClient ftpClient;
public FTP() {
this.hostName = "192.168.1.101";
this.serverPort = 21;
this.userName = "admin";
this.password = "1234";
this.ftpClient = new FTPClient();
}
// -------------------------------------------------------文件上傳方法------------------------------------------------
/**
* 上傳單個文件.
*
* @param localFile
* 本地文件
* @param remotePath
* FTP目錄
* @param listener
* 監(jiān)聽器
* @throws IOException
*/
public void uploadSingleFile(File singleFile, String remotePath,
UploadProgressListener listener) throws IOException {
// 上傳之前初始化
this.uploadBeforeOperate(remotePath, listener);
boolean flag;
flag = uploadingSingle(singleFile, listener);
if (flag) {
listener.onUploadProgress(MainActivity.FTP_UPLOAD_SUCCESS, 0,
singleFile);
} else {
listener.onUploadProgress(MainActivity.FTP_UPLOAD_FAIL, 0,
singleFile);
}
// 上傳完成之后關(guān)閉連接
this.uploadAfterOperate(listener);
}
/**
* 上傳多個文件.
*
* @param localFile
* 本地文件
* @param remotePath
* FTP目錄
* @param listener
* 監(jiān)聽器
* @throws IOException
*/
public void uploadMultiFile(LinkedList<File> fileList, String remotePath,
UploadProgressListener listener) throws IOException {
// 上傳之前初始化
this.uploadBeforeOperate(remotePath, listener);
boolean flag;
for (File singleFile : fileList) {
flag = uploadingSingle(singleFile, listener);
if (flag) {
listener.onUploadProgress(MainActivity.FTP_UPLOAD_SUCCESS, 0,
singleFile);
} else {
listener.onUploadProgress(MainActivity.FTP_UPLOAD_FAIL, 0,
singleFile);
}
}
// 上傳完成之后關(guān)閉連接
this.uploadAfterOperate(listener);
}
/**
* 上傳單個文件.
*
* @param localFile
* 本地文件
* @return true上傳成功, false上傳失敗
* @throws IOException
*/
private boolean uploadingSingle(File localFile,
UploadProgressListener listener) throws IOException {
boolean flag = true;
// 不帶進(jìn)度的方式
// // 創(chuàng)建輸入流
// InputStream inputStream = new FileInputStream(localFile);
// // 上傳單個文件
// flag = ftpClient.storeFile(localFile.getName(), inputStream);
// // 關(guān)閉文件流
// inputStream.close();
// 帶有進(jìn)度的方式
BufferedInputStream buffIn = new BufferedInputStream(
new FileInputStream(localFile));
ProgressInputStream progressInput = new ProgressInputStream(buffIn,
listener, localFile);
flag = ftpClient.storeFile(localFile.getName(), progressInput);
buffIn.close();
return flag;
}
/**
* 上傳文件之前初始化相關(guān)參數(shù)
*
* @param remotePath
* FTP目錄
* @param listener
* 監(jiān)聽器
* @throws IOException
*/
private void uploadBeforeOperate(String remotePath,
UploadProgressListener listener) throws IOException {
// 打開FTP服務(wù)
try {
this.openConnect();
listener.onUploadProgress(MainActivity.FTP_CONNECT_SUCCESSS, 0,
null);
} catch (IOException e1) {
e1.printStackTrace();
listener.onUploadProgress(MainActivity.FTP_CONNECT_FAIL, 0, null);
return;
}
// 設(shè)置模式
ftpClient.setFileTransferMode(org.apache.commons.net.ftp.FTP.STREAM_TRANSFER_MODE);
// FTP下創(chuàng)建文件夾
ftpClient.makeDirectory(remotePath);
// 改變FTP目錄
ftpClient.changeWorkingDirectory(remotePath);
// 上傳單個文件
}
/**
* 上傳完成之后關(guān)閉連接
*
* @param listener
* @throws IOException
*/
private void uploadAfterOperate(UploadProgressListener listener)
throws IOException {
this.closeConnect();
listener.onUploadProgress(MainActivity.FTP_DISCONNECT_SUCCESS, 0, null);
}
// -------------------------------------------------------文件下載方法------------------------------------------------
/**
* 下載單個文件,可實(shí)現(xiàn)斷點(diǎn)下載.
*
* @param serverPath
* Ftp目錄及文件路徑
* @param localPath
* 本地目錄
* @param fileName
* 下載之后的文件名稱
* @param listener
* 監(jiān)聽器
* @throws IOException
*/
public void downloadSingleFile(String serverPath, String localPath, String fileName, DownLoadProgressListener listener)
throws Exception {
// 打開FTP服務(wù)
try {
this.openConnect();
listener.onDownLoadProgress(MainActivity.FTP_CONNECT_SUCCESSS, 0, null);
} catch (IOException e1) {
e1.printStackTrace();
listener.onDownLoadProgress(MainActivity.FTP_CONNECT_FAIL, 0, null);
return;
}
// 先判斷服務(wù)器文件是否存在
FTPFile[] files = ftpClient.listFiles(serverPath);
if (files.length == 0) {
listener.onDownLoadProgress(MainActivity.FTP_FILE_NOTEXISTS, 0, null);
return;
}
//創(chuàng)建本地文件夾
File mkFile = new File(localPath);
if (!mkFile.exists()) {
mkFile.mkdirs();
}
localPath = localPath + fileName;
// 接著判斷下載的文件是否能斷點(diǎn)下載
long serverSize = files[0].getSize(); // 獲取遠(yuǎn)程文件的長度
File localFile = new File(localPath);
long localSize = 0;
if (localFile.exists()) {
localSize = localFile.length(); // 如果本地文件存在,獲取本地文件的長度
if (localSize >= serverSize) {
File file = new File(localPath);
file.delete();
}
}
// 進(jìn)度
long step = serverSize / 100;
long process = 0;
long currentSize = 0;
// 開始準(zhǔn)備下載文件
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的進(jìn)度返回一次
listener.onDownLoadProgress(MainActivity.FTP_DOWN_LOADING, process, null);
}
}
}
out.flush();
out.close();
input.close();
// 此方法是來確保流處理完畢,如果沒有此方法,可能會造成現(xiàn)程序死掉
if (ftpClient.completePendingCommand()) {
listener.onDownLoadProgress(MainActivity.FTP_DOWN_SUCCESS, 0, new File(localPath));
} else {
listener.onDownLoadProgress(MainActivity.FTP_DOWN_FAIL, 0, null);
}
// 下載完成之后關(guān)閉連接
this.closeConnect();
listener.onDownLoadProgress(MainActivity.FTP_DISCONNECT_SUCCESS, 0, null);
return;
}
// -------------------------------------------------------文件刪除方法------------------------------------------------
/**
* 刪除Ftp下的文件.
*
* @param serverPath
* Ftp目錄及文件路徑
* @param listener
* 監(jiān)聽器
* @throws IOException
*/
public void deleteSingleFile(String serverPath, DeleteFileProgressListener listener)
throws Exception {
// 打開FTP服務(wù)
try {
this.openConnect();
listener.onDeleteProgress(MainActivity.FTP_CONNECT_SUCCESSS);
} catch (IOException e1) {
e1.printStackTrace();
listener.onDeleteProgress(MainActivity.FTP_CONNECT_FAIL);
return;
}
// 先判斷服務(wù)器文件是否存在
FTPFile[] files = ftpClient.listFiles(serverPath);
if (files.length == 0) {
listener.onDeleteProgress(MainActivity.FTP_FILE_NOTEXISTS);
return;
}
//進(jìn)行刪除操作
boolean flag = true;
flag = ftpClient.deleteFile(serverPath);
if (flag) {
listener.onDeleteProgress(MainActivity.FTP_DELETEFILE_SUCCESS);
} else {
listener.onDeleteProgress(MainActivity.FTP_DELETEFILE_FAIL);
}
// 刪除完成之后關(guān)閉連接
this.closeConnect();
listener.onDeleteProgress(MainActivity.FTP_DISCONNECT_SUCCESS);
return;
}
// -------------------------------------------------------打開關(guān)閉連接------------------------------------------------
/**
* 打開FTP服務(wù).
*
* @throws IOException
*/
public void openConnect() throws IOException {
// 中文轉(zhuǎn)碼
ftpClient.setControlEncoding("UTF-8");
int reply; // 服務(wù)器響應(yīng)值
// 連接至服務(wù)器
ftpClient.connect(hostName, serverPort);
// 獲取響應(yīng)值
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
// 斷開連接
ftpClient.disconnect();
throw new IOException("connect fail: " + reply);
}
// 登錄到服務(wù)器
ftpClient.login(userName, password);
// 獲取響應(yīng)值
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);
// 使用被動模式設(shè)為默認(rèn)
ftpClient.enterLocalPassiveMode();
// 二進(jìn)制文件支持
ftpClient
.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
}
}
/**
* 關(guān)閉FTP服務(wù).
*
* @throws IOException
*/
public void closeConnect() throws IOException {
if (ftpClient != null) {
// 退出FTP
ftpClient.logout();
// 斷開連接
ftpClient.disconnect();
}
}
// ---------------------------------------------------上傳、下載、刪除監(jiān)聽---------------------------------------------
/*
* 上傳進(jìn)度監(jiān)聽
*/
public interface UploadProgressListener {
public void onUploadProgress(String currentStep, long uploadSize, File file);
}
/*
* 下載進(jìn)度監(jiān)聽
*/
public interface DownLoadProgressListener {
public void onDownLoadProgress(String currentStep, long downProcess, File file);
}
/*
* 文件刪除監(jiān)聽
*/
public interface DeleteFileProgressListener {
public void onDeleteProgress(String currentStep);
}
}
3. ProgressInputStream
package com.ftp;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import com.ftp.FTP.UploadProgressListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class ProgressInputStream extends InputStream {
private static final int TEN_KILOBYTES = 1024 * 10; //每上傳10K返回一次
private InputStream inputStream;
private long progress;
private long lastUpdate;
private boolean closed;
private UploadProgressListener listener;
private File localFile;
public ProgressInputStream(InputStream inputStream,UploadProgressListener listener,File localFile) {
this.inputStream = inputStream;
this.progress = 0;
this.lastUpdate = 0;
this.listener = listener;
this.localFile = localFile;
this.closed = false;
}
@Override
public int read() throws IOException {
int count = inputStream.read();
return incrementCounterAndUpdateDisplay(count);
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int count = inputStream.read(b, off, len);
return incrementCounterAndUpdateDisplay(count);
}
@Override
public void close() throws IOException {
super.close();
if (closed)
throw new IOException("already closed");
closed = true;
}
private int incrementCounterAndUpdateDisplay(int count) {
if (count > 0)
progress += count;
lastUpdate = maybeUpdateDisplay(progress, lastUpdate);
return count;
}
private long maybeUpdateDisplay(long progress, long lastUpdate) {
if (progress - lastUpdate > TEN_KILOBYTES) {
lastUpdate = progress;
this.listener.onUploadProgress(MainActivity.FTP_UPLOAD_LOADING, progress, this.localFile);
}
return lastUpdate;
}
}
原文鏈接:http://blog.csdn.net/tianyitianyi1/article/details/38637999
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android?無障礙服務(wù)?performAction?調(diào)用過程分析
這篇文章主要介紹了Android?無障礙服務(wù)?performAction?調(diào)用過程分析,無障礙服務(wù)可以模擬一些用戶操作,無障礙可以處理的對象,通過類?AccessibilityNodeInfo?表示,通過無障礙服務(wù),可以通過它的performAction方法來觸發(fā)一些action2022-06-06
android之App Widget開發(fā)實(shí)例代碼解析
本篇文章主要介紹了App Widget框架的實(shí)例應(yīng)用,AppWidget就是我們平常在桌面上見到的那種一個個的小窗口,利用這個小窗口可以給用戶提供一些方便快捷的操作。有需要的可以了解一下。2016-11-11
Android 客戶端RSA加密的實(shí)現(xiàn)方法
這篇文章主要介紹了Android 客戶端RSA加密的實(shí)現(xiàn)方法的相關(guān)資料,希望通過本文能掌握RSA 的使用,需要的朋友可以參考下2017-08-08
實(shí)例講解Android多線程應(yīng)用開發(fā)中Handler的使用
這篇文章主要介紹了Android多線程應(yīng)用開發(fā)中Handler的使用,Handle主要被用來更新UI和處理消息,需要的朋友可以參考下2016-01-01
Android仿今日頭條多個fragment懶加載的實(shí)現(xiàn)
我們在做應(yīng)用開發(fā)的時候,一個Activity里面可能會以viewpager(或其他容器)與多個Fragment來組合使用,下面這篇文章主要給大家介紹了關(guān)于利用Android仿今日頭條多個fragment懶加載的相關(guān)資料,需要的朋友可以參考下。2017-12-12
Android SharedPreferences實(shí)現(xiàn)保存登錄數(shù)據(jù)功能
這篇文章主要為大家詳細(xì)介紹了Android SharedPreferences實(shí)現(xiàn)保存登錄數(shù)據(jù)功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-05-05
Android實(shí)現(xiàn)信號強(qiáng)度監(jiān)聽的方法
這篇文章主要介紹了Android實(shí)現(xiàn)信號強(qiáng)度監(jiān)聽的方法,是Android手機(jī)中很常見的一個實(shí)用功能,需要的朋友可以參考下2014-08-08
Android自定義控件ScrollView實(shí)現(xiàn)上下滑動功能
這篇文章主要為大家詳細(xì)介紹了Android自定義控件ScrollView實(shí)現(xiàn)上下滑動功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07

