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是一种为了将位于全球各个地方的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) { // 退出FTP ftpClient.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() { @Override public 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系列之网络(一)----使用HttpClient发送HTTP请求(通过get方法获取数据)