本文属于学习分享,如有雷同纯属巧合
利用业余时间,学习一些有用的东西,如果手又有点贱的话,不妨自己也跟着敲起来。
在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() { @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的话,请自行下载哦。
点击这里下载吧。
版权声明:本文为博主原创文章,未经博主允许不得转载。