FTP 是File Transfer Protocol(文件传输协议)的英文简称,从这个名字也能看出来,这个协议是为了文件传输而生的。

使用前需要下载一个commons-net-3.3.jar

直接看上传代码

/** * 向FTP服务器上传文件 *  * @param url *            FTP服务器hostname 就是ip* @param port 21*            端口默认80 * @param username *            用户名 * @param password *            密码 * @param path *            FTP服务器保存目录* @param filename*            文件名称 上传到FTP服务器上的文件名,是自己定义的名字 * @param input *            文件输入流 * @return */  public static boolean upload(String url, int port, String username,  String password, String path, String filename, InputStream input) {  boolean success = false;  FTPClient ftp = new FTPClient();  try {  ftp.setDataTimeout(2000);//设置连接超时时间  ftp.connect(url, port); // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器  ftp.login(username, password); if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {  ftp.disconnect();  //未连接到FTP,用户名或密码错误return success;  }  boolean isExist =  createDirecroty(path,ftp) ;  if(!isExist){  return success;  }  //获取服务器当前目录指定文件信息FTPFile[] files = ftp.listFiles(filename);if(files.length > 1){ftp.deleteFile(filename);}ftp.setControlEncoding("UTF-8");ftp.setBufferSize(1024);  ftp.enterLocalPassiveMode();    ftp.setFileType(FTP.BINARY_FILE_TYPE);  //处理中文名称的文件名,如果不加这一句的话,中文命名的文件是不能上传的  filename = new String(filename.getBytes("GBK"), "iso-8859-1") ;  ftp.storeFile(filename, input);  input.close();  ftp.logout(); success = true;  } catch (IOException e) {e.printStackTrace();  } finally {  if (ftp.isConnected()) {  try {  ftp.disconnect();  } catch (IOException ioe) {  }  }  }  return success;  }  /*** 递归创建远程服务器目录* * @param remote*            远程服务器文件绝对路径* @return 目录创建是否成功* @throws IOException*/public static boolean createDirecroty(String remote,FTPClient ftp) throws IOException {String totalPath = "";boolean success = true;String[] path = remote.split("/");for(int i=0; i<path.length; i++){            String father = path[i];if(father == null || "".equals(father)){success = false;break;}totalPath = totalPath + "/"+father;try {boolean isExit = ftp.changeWorkingDirectory(totalPath);if(!isExit){boolean make = ftp.makeDirectory(totalPath);if(!make){success = false;break;}//工作路径切换到此boolean change = ftp.changeWorkingDirectory(totalPath);if(!change){success = false;break;}}} catch (IOException e) {success = false;break;}}  return success;}

流程其实很简单的,就是先连接FTP服务器(这里要求你的服务器支持FTP协议),再登陆,然后再创建相关目录,记住目录要一级一级创建,然后就是通过ftp上传了。这里其实看不到上传进度,就下来看另外一个方法

public static boolean upload(String url, int port, String username,  String password, String remotePath, File localFile) {  boolean success = false;  RandomAccessFile raf = null;OutputStream output = null;FTPClient ftp = new FTPClient();  try {  ftp.connect(url, port); // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器  ftp.login(username, password); int reply = ftp.getReplyCode();if (!FTPReply.isPositiveCompletion(reply)) {  ftp.disconnect();  //未连接到FTP,用户名或密码错误return success;  }  boolean isExist =  createDirecroty(remotePath,ftp) ;  if(!isExist){  return success;  }  //获取当前目录指定文件信息FTPFile[] files = ftp.listFiles(localFile.getName());if(files.length > 1){ftp.deleteFile(localFile.getName());}raf = new RandomAccessFile(localFile, "r");  long serverSize = 0;/* enterLocalPassiveMode * 每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。* 为什么要这样做呢,因为ftp server可能每次开启不同的端口来传输数据,* 但是在linux上或者其他服务器上面,由于安全限制,可能某些端口没有开启,* 所以就出现阻塞* */ftp.enterLocalPassiveMode();  ftp.setFileType(FTP.BINARY_FILE_TYPE);//设置二进制传输,还支持传输ACSII数据  ftp.setRestartOffset(serverSize);  raf.seek(serverSize);  // 进度  long localSize = localFile.length(); // 本地文件的长度 long step = localSize / 100;  long process = 0;  long currentSize = 0; String filename = localFile.getName();filename = new String(filename.getBytes("GBK"), "iso-8859-1") ;  output = ftp.appendFileStream(filename);  byte[] b = new byte[1024];  int length = 0;  while ((length = raf.read(b)) != -1) {  output.write(b, 0, length);  currentSize = currentSize + length;  if (currentSize / step != process) {  process = currentSize / step;  Log.e(TAG, "上传进度:" + process);}  }  if (ftp.completePendingCommand()) {success = true; Log.e(TAG, "文件上传成功");} } catch (IOException e) {e.printStackTrace();  } finally {  try {output.flush();output.close();} catch (IOException e) {e.printStackTrace();}  try {raf.close();} catch (IOException e1) {e1.printStackTrace();} try {ftp.logout();} catch (IOException e) {e.printStackTrace();}if (ftp.isConnected()) {  try {  ftp.disconnect();  } catch (IOException ioe) {  }  }  }  return success;  }

这里就是通过appendFileStream方法获取输出流来进行进度获取。

还可以通过ftp.setRestartOffset(serverSize);  raf.seek(serverSize);  来进行断点上传

上传结束,再来看下载

public static boolean downloadFile(String url, int port, String username,  String password, String localPath, String serverPath){  boolean success = false;  FTPClient ftpClient = new FTPClient();try {ftpClient.setControlEncoding("GBK"); ftpClient.connect(url, port);ftpClient.login(username, password);if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {  ftpClient.disconnect();  //未连接到FTP,用户名或密码错误return false;    }// 先判断服务器文件是否存在  FTPFile[] files = ftpClient.listFiles(serverPath);  if (files.length == 0) {  Log.e(TAG,"服务器文件不存在 serverPath="+serverPath);  return false;  }  localPath = localPath + files[0].getName();  long serverSize = files[0].getSize(); // 获取远程文件的长度  File localFile = new File(localPath);  long localSize = 0;  if (localFile.exists()) {  localFile.delete(); }  // 进度  long step = serverSize / 100;  long process = 0;  long currentSize = 0;  // 开始准备下载文件  ftpClient.enterLocalActiveMode();  ftpClient.setFileType(FTP.BINARY_FILE_TYPE);  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;  Log.e(TAG,"下载进度:" + process);   }  }  out.flush();  out.close();  input.close();  // 此方法是来确保流处理完毕,如果没有此方法,可能会造成现程序死掉  if (ftpClient.completePendingCommand()) {  Log.e(TAG,"文件下载成功");  success = true;} } catch (SocketException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return success;}

这里就是通过retrieveFileStream获取输入流进行下载。

再看看使用HTTP进行文件上传

    /*** 通过拼接的方式构造请求内容,实现参数传输以及文件传输* * @param url http://192.168.1.19:8080/web/servlet/UploadServlet* @param params text content* @param files pictures* @return String result of Service response* @throws IOException*/public static String post(String url, Map<String, String> params, Map<String, File> files)throws IOException {String BOUNDARY = java.util.UUID.randomUUID().toString();String PREFIX = "--";String LINEND = "\r\n";String MULTIPART_FROM_DATA = "multipart/form-data";String CHARSET = "UTF-8";URL uri = new URL(url);HttpURLConnection conn = (HttpURLConnection) uri.openConnection();conn.setReadTimeout(10 * 1000); conn.setDoInput(true);// 允许输入conn.setDoOutput(true);// 允许输出conn.setUseCaches(false); // 不允许使用缓存conn.setRequestMethod("POST");conn.setRequestProperty("connection", "keep-alive");conn.setRequestProperty("Charsert", "UTF-8");conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);conn.setChunkedStreamingMode(1024);// 首先组拼文本类型的参数StringBuilder sb = new StringBuilder();for (Map.Entry<String, String> entry : params.entrySet()) {sb.append(PREFIX);sb.append(BOUNDARY);sb.append(LINEND);sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINEND);sb.append("Content-Type: text/plain; charset=" + CHARSET + LINEND);sb.append("Content-Transfer-Encoding: 8bit" + LINEND);sb.append(LINEND);sb.append(entry.getValue());sb.append(LINEND);}DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());outStream.write(sb.toString().getBytes());// 发送文件数据if (files != null)for (Map.Entry<String, File> file : files.entrySet()) {StringBuilder sb1 = new StringBuilder();sb1.append(PREFIX);sb1.append(BOUNDARY);sb1.append(LINEND);sb1.append("Content-Disposition: form-data; name=\"uploadfile\"; filename=\""+ file.getValue().getName() + "\"" + LINEND);sb1.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINEND);sb1.append(LINEND);outStream.write(sb1.toString().getBytes());InputStream is = new FileInputStream(file.getValue());byte[] buffer = new byte[1024];int len = 0;while ((len = is.read(buffer)) != -1) {outStream.write(buffer, 0, len);}is.close();outStream.write(LINEND.getBytes());}// 请求结束标志byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();outStream.write(end_data);outStream.flush();// 得到响应码int res = conn.getResponseCode();//获取服务器返回结果InputStream in = conn.getInputStream();StringBuilder sb2 = new StringBuilder();if (res == 200) {int ch;while ((ch = in.read()) != -1) {sb2.append((char) ch);}}outStream.close();conn.disconnect();return sb2.toString();}//调用方式如下public String uploadFile(File f){final Map<String, String> params = new HashMap<String, String>();params.put("sessionId", "123456");final Map<String, File> files = new HashMap<String, File>();files.put("uploadfile",f);String response=null;try {response = UploadUtil.post(FAULT_FILEUPLOAD_URL, params, files);} catch (IOException e) {e.printStackTrace();}return response;}

使用HTTP进行文件下载其实就是获取输入流数据,然后通过输出流写到文件里,主要代码跟上面FTP下载差不多

至于使用哪个协议下载好,就要看具体情况了,对个人而言没啥区别

FTP协议是专门用于文件传输的协议,网络传输更加安全

HTTP只是超文本传输协议,最原始的目的仅仅只是为了将超文本的信息(包括图象视频等)传到你的机子上就行了,但是使用方便

Android开发-使用FTP协议和HTTP协议进行文件下载和上传相关推荐

  1. FTP 协议和 HTTP 协议的比较

    参考:http://www.oschina.net/news/28162/http-vs-ftp 以下列出了一些两者的不同点: 1.HTTP协议是用来浏览网站的,而FTP是用来访问和传输文件的,FTP ...

  2. 网络协议丨FTP协议和P2P协议

    现在不管是下载文件还是浏览内容,我们都是使用HTTP协议. 但是除了HTTP协议以外,也存在其他的协议. 比如文件下载,就有FTP协议,也就是文件传输协议.FTP 采用两个 TCP 连接来传输一个文件 ...

  3. Android网络功能开发(4)——文件下载和上传

    本篇介绍使用HTTP协议实现文件下载和上传.在客户端和服务器的通信过程中,可能有些多媒体或数据文件需要下载或上传,可以通过HTTP协议实现. 首先看使用HTTP协议下载文件的原理:客户端发送一个HTT ...

  4. tcp协议和udp协议区别_TCP和UDP协议有什么区别?

    tcp协议和udp协议区别 TCP and UDP are two protocols that are part of the transport layer in a TCP/IP model o ...

  5. SSL协议和SET协议

    SSL协议和SET协议 --三.安全电子交易的协议 --目前的安全电子交易协议主要有两种,即安全套接层(SSL)协议和安全电子交易(SET)协议. --1.SSL协议 --SSL协议由Netscape ...

  6. 计算机网络整理:UDP协议和TCP协议

    系列文章目录 HTTP协议和HTTPS协议 文章目录 系列文章目录 一.TCP/IP 各层协议 二.UDP协议和TCP协议 1.TCP和UDP的区别 2.UDP 协议 3.TCP 协议 1)特点 2) ...

  7. RabbitMQ MQTT协议和AMQP协议

    RabbitMQ MQTT协议和AMQP协议 1        序言... 1 1.1     RabbitMq结构... 1 1.2     RabbitMq消息接收... 4 1.3     Ex ...

  8. 计算机网络(二十)-广域网-PPP协议和HDLC协议

    一.广域网 广域网,通常跨接很大的物理范围,所覆盖的范围从几十公里到几千公里,它能连接多个城市或国家,远距离通信,形成国际性的远程网络. 广域网的通信子网主要使用分组交换技术.广域网的通信子网可以利用 ...

  9. STM8单片机串口同时识别自定义协议和Modbus协议

      在单片机开发中,串口是最常用的和外界交换数据的渠道,要使用串口,那必不可少的就是通信协议,通信协议就是单片机和外界通信的语言,要想正常和其他设备正常交流,首先语言必须相通.   在实际开发过程中由 ...

最新文章

  1. C#精粹,一本都不能少
  2. 设计模式 — 行为型模式 — 中介者模式
  3. Word 2010中利用尾注添加参考文献(论文必备)
  4. net-snmp交叉编译出现 undefined reference to dlopen,dlsym,dlclose错误
  5. Nettiers快速使用入门(一) 数据库
  6. 2014年第五届蓝桥杯C/C++ A组国赛 —— 第一题:海盗分金币
  7. ActiveMQ性能测试
  8. 34tomcat设置默认页面
  9. 可以运行python的路由器_用python管理Cisco路由器
  10. iOS Core Animation Advanced Techniques-图层树
  11. 2008 r2 server sql 中文版补丁_SQL Server 2008 R2 补丁
  12. win10无法装载iso文件_win10系统解决方案无法打开iso文件
  13. linux抓包-tcpdump
  14. ios UIImageView 部分圆角(加上 borderWidth、borderColor 效果修复)
  15. 表格识别综述与相关实战
  16. 最简单代码画的五角星
  17. 中盈Zonewin NX-1900 打印机驱动
  18. Linux系列之CentOS系统安装
  19. CentOS 环境下的一些配置(安装软件)
  20. Windows 配置Java环境

热门文章

  1. 常识:UI行业常用名词及缩写定义
  2. git stash用法
  3. 你的万圣节专属头像生成器,快来试试(内附家喵营业照)
  4. 数学模型在水环境影响评价、防洪评价与排污口论证项目中的应用
  5. 关于Google的Suggest功能的实现
  6. java获取当前时间年月_Java获取时间年、月、日的方法
  7. 安卓手机开机动画制作原理教程
  8. Javascript节点
  9. 【网络】网络基础知识详解
  10. 对学生生涯的总结以及对步入社会的规划与展望