FTP 概述

文件传输协议(FTP)作为网络共享文件的传输协议,在网络应用软件中具有广泛的应用。FTP的目标是提高文件的共享性和可靠高效地传送数据。

在传输文件时,FTP 客户端程序先与服务器建立连接,然后向服务器发送命令。服务器收到命令后给予响应,并执行命令。FTP 协议与操作系统无关,任何操作系统上的程序只要符合 FTP 协议,就可以相互传输数据。

FTP 协议

相比其他协议,如 HTTP 协议,FTP 协议要复杂一些。与一般的 C/S 应用不同点在于一般的C/S 应用程序一般只会建立一个 Socket 连接,这个连接同时处理服务器端和客户端的连接命令和数据传输。而FTP协议中将命令与数据分开传送的方法提高了效率。

FTP 使用 2 个端口,一个数据端口和一个命令端口(也叫做控制端口)。这两个端口一般是21 (命令端口)和 20 (数据端口)。控制 Socket 用来传送命令,数据 Socket 是用于传送数据。每一个 FTP 命令发送之后,FTP 服务器都会返回一个字符串,其中包括一个响应代码和一些说明信息。其中的返回码主要是用于判断命令是否被成功执行了。

基于FtpClient实现的Ftp连接实现原理层也是通过Socket来实现的

以下是示例代码:

package com.test;import java.io.DataInputStream;
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.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;import sun.net.ftp.FtpClient;
import sun.net.ftp.FtpProtocolException;/*** Java自带的API对FTP的操作* * 文件名称:FtpUtil.java*/
public final class FtpUtil {private FtpUtil(){}public final static int BUFF_SIZE = 1024;/*** ftp文件上传* @param connectionString ftp协议链接字符串 ftp://用户名:密码@地址:端口/ 或  ftp://地址:端口/* @param localFile 本地文件或文件夹* @param isOver 是否覆盖存在文件* @throws RuntimeException */@SuppressWarnings("restriction")public final static void upload(String connectionString, File localFile, boolean isOver) throws RuntimeException{if(!localFile.exists()){throw new RuntimeException("local file is exists!");}FtpClient ftpClient = connect(connectionString);try {upload(ftpClient, localFile, isOver);}finally {try{ftpClient.close();}catch(Exception ex){throw new RuntimeException(ex);}}}/*** ftp文件上传* @param connectionString ftp协议链接字符串 ftp://用户名:密码@地址:端口/ 或  ftp://地址:端口/* @param remoteFile ftp服务器文件名称* @param fileStream 待写入文件流* @param isOver 是否覆盖存在文件* @throws RuntimeException*/@SuppressWarnings("restriction")public final static void upload(String connectionString, String remoteFile, InputStream fileStream, boolean isOver) throws RuntimeException {FtpClient ftpClient = connect(connectionString);try {if(!"".equals(ftpClient.getStatus(remoteFile)) && !isOver)//是否覆盖文件return;try (OutputStream os = ftpClient.putFileStream(remoteFile); InputStream is = fileStream) {byte[] bytes = new byte[BUFF_SIZE];// 创建一个缓冲区int c;while ((c = is.read(bytes)) > 0) {os.write(bytes, 0, c);}}} catch(Exception ex){throw new RuntimeException("input stream write fail!", ex);}finally {try{ftpClient.close();}catch(Exception ex){throw new RuntimeException(ex);}}}/*** 文件上传* @param ftpClient ftp客户端句柄* @param localFile 本地文件或文件夹* @param isOver 是否覆盖存在文件* @throws RuntimeException*/@SuppressWarnings("restriction")private static void upload(FtpClient ftpClient, File localFile, boolean isOver) throws RuntimeException {if(localFile.isDirectory()){try{try{ftpClient.changeDirectory(localFile.getName());}catch(Exception ex){ftpClient.makeDirectory(localFile.getName());ftpClient.changeDirectory(localFile.getName());}String[] files = localFile.list();File tempFile;for (int i = 0; i < files.length; i++) {        tempFile = new File(localFile.getPath()+"\\"+files[i] );        if(tempFile.isDirectory()){        upload(ftpClient, tempFile, isOver);        ftpClient.changeToParentDirectory();        }else{                      tempFile = new File(localFile.getPath()+"\\"+files[i]);        streamWrite(ftpClient, tempFile, isOver);}                   }        }catch(Exception ex){throw new RuntimeException(ex);}}else{        streamWrite(ftpClient, localFile, isOver);}        } /*** 文件写入到ftp服务器* @param ftpClient ftp客户端句柄* @param localFile 本地文件* @param isOver 是否覆盖存在文件* @throws RuntimeException*/@SuppressWarnings("restriction")private static void streamWrite(FtpClient ftpClient, File localFile, boolean isOver) throws RuntimeException{try{if(!"".equals(ftpClient.getStatus(localFile.getName())) && !isOver)//是否覆盖文件return;try (OutputStream os = ftpClient.putFileStream(localFile.getName());InputStream is = new FileInputStream(localFile)) {byte[] bytes = new byte[BUFF_SIZE];// 创建一个缓冲区int c;while ((c = is.read(bytes)) > 0) {os.write(bytes, 0, c);}}}catch(Exception ex){throw new RuntimeException(ex);}}/** * 从ftp下载文件到本地 *  * @param filename 服务器上的文件名 * @param newfilename 本地生成的文件名 * @return * @throws Exception */  @SuppressWarnings("restriction")public static long downloadFile(FtpClient ftpClient, String filename, String newfilename) {long result = 0;InputStream is = null;FileOutputStream os = null;try {is = ftpClient.getFileStream(filename);java.io.File outfile = new java.io.File(newfilename);os = new FileOutputStream(outfile);byte[] bytes = new byte[is.available()];int c;while ((c = is.read(bytes)) != -1) {os.write(bytes, 0, c);result = result + c;}} catch (IOException | FtpProtocolException e) {e.printStackTrace();} finally {try {if (is != null) {is.close();}if (os != null) {os.close();}} catch (IOException e) {e.printStackTrace();}}return result;}/** * 取得相对于当前连接目录的某个目录下所有文件列表 *  * @param path * @return * @throws FtpProtocolException */  @SuppressWarnings("restriction")public static List<Object> getFileList(FtpClient ftpClient,String path) throws FtpProtocolException{  List<Object> list = new ArrayList<Object>();  DataInputStream dis;  try {  dis = new DataInputStream(ftpClient.nameList( path));  String filename = "";  while((filename = dis.readLine()) != null){  list.add(filename);  }  } catch (IOException e) {  e.printStackTrace();  }  return list;  }  /*** 连接到ftp服务器* @param ip ftp服务器地址* @param port ftp服务器端口* @param user 登陆ftp服务器用户* @param password 登陆ftp服务器用户密码* @param remotePath ftp服务器文件路径* @return FtpClient* @throws RuntimeException*/@SuppressWarnings("restriction")private static FtpClient connect(String ip, int port, String user, String password, String remotePath) throws RuntimeException {FtpClient ftpClient = FtpClient.create();SocketAddress addr = new InetSocketAddress(ip, port);try{ftpClient.connect(addr);ftpClient.login(user, password.toCharArray());ftpClient.setBinaryType();if (remotePath!=null && remotePath.length() != 0) { // 把远程系统上的目录切换到参数path所指定的目录String[] paths=remotePath.split("/");for(String path : paths){if(path.length() == 0)continue;try{ftpClient.changeDirectory(path);}catch(FtpProtocolException ex){ftpClient.makeDirectory(path);ftpClient.changeDirectory(path);}}}return ftpClient;}catch(Exception ex){throw new RuntimeException(ex);}}/*** 连接到ftp服务器* @param connectionString 链接字符串* @return*/@SuppressWarnings("restriction")private static FtpClient connect(String connectionString) throws RuntimeException{Pattern pattern = Pattern.compile("^ftp://(?:\\S+?:\\S+?@)?\\S+?(?:\\d+?)?");if(pattern.matcher(connectionString).find()){String autho = "anonymous", uri = connectionString.substring("ftp://".length()).replace("\\", "/"),user = "anonymous",pwd = "", ip = "", remotePath = "";int sp = uri.indexOf("/"), port = 21;if(sp >= 0){remotePath = uri.substring(sp);uri = uri.substring(0, sp);}sp = uri.lastIndexOf("@");if(sp >= 0){autho = uri.substring(0, sp);uri = ip = uri.substring(sp + 1);}sp = autho.lastIndexOf(":");if(sp >= 0){user = autho.substring(0, sp);pwd  = autho.substring(sp + 1);}sp = uri.lastIndexOf(":");if(sp >= 0){ip = uri.substring(0, sp);port  = Integer.parseInt(uri.substring(sp + 1));}return connect(ip, port, user, pwd, remotePath);}throw new RuntimeException("connectionString is invalid!");}/** * 断开与ftp服务器连接 *  * @throws IOException */ @SuppressWarnings("restriction")public static boolean closeServer(FtpClient ftpClient) {  try {  if (ftpClient != null) {  //ftpClient.closeServer();  ftpClient.close();}  System.out.println("已从服务器断开");  return true;  } catch (IOException e) {  e.printStackTrace();  return false;  }  }  @SuppressWarnings("restriction")public static void main(String[] args) throws FtpProtocolException {FtpClient ftpClient=connect("192.168.10.11", 22, "test_ftp", "test_123", "/test");System.out.println("===="+ftpClient.isPassiveModeEnabled());//upload(ftpClient, new File("E:\\test\\test12.txt"), true);System.out.println("getFileList: "+getFileList(ftpClient, "/test").get(0));long ll=downloadFile(ftpClient, "/test/test.txt", "E:\\test\\test.txt");System.out.println("long : "+ll);closeServer(ftpClient);}
}

参考自 http://blog.csdn.net/wochunyang/article/details/53332557

基于FtpClient(JDK1.7)实现Ftp连接相关推荐

  1. Java基于FTPClient上传文件到FTP服务器

    1.上传文件到FTP服务器,用FTPClient类,引入commons-net-3.1.jar包 2.参考代码: //上传ftppublic static boolean uploadFile(Str ...

  2. 基于socket通信实现Ftp连接

    FTP 概述 文件传输协议(FTP)作为网络共享文件的传输协议,在网络应用软件中具有广泛的应用.FTP的目标是提高文件的共享性和可靠高效地传送数据. 在传输文件时,FTP 客户端程序先与服务器建立连接 ...

  3. java ftp上传超时_java - Java FTP连接超时 - 堆栈内存溢出

    我正在做一个项目,修改后,稍后会将一些文件上传到FTP服务器...除了弄清楚文件的上传之外,我什么都没有. 我可以成功连接到FTP服务器,但是一旦文件上传,该程序将挂起几分钟,然后显示超时. java ...

  4. java ftp封装_使用FTP连接池封装Java工具类

    使用FTP连接池封装工具类 背景 早前的思路是将FTP连接的管理(对象池功能)与FTP工具类(上传下载方法)在一个工程中实现,在工具类中调用是模板类提供的模板方法, 由模板方法与对象池打交道--初始时 ...

  5. java实现ftp连接、登陆、上传、下载、删除文件、获取目录、文件列表

    全栈工程师开发手册 (作者:栾鹏) java教程全解 java实现ftp连接.登陆.上传.下载.删除文件.获取目录.文件列表等操作. 本地调试,首先需要在本机上开启ftp服务和ftp站点. 测试代码 ...

  6. java关闭ftp 连接_Java语言实现简单FTP软件------gt;连接管理模块的实现:主机与服务器之间的连接与关闭操作(八) - 移动编程 - ITeye博客...

    (1)FTP连接 运行FTP客户端后,首先是连接FTP服务器,需要输入FTP服务器的IP地址及用户名.密码以及端口号后点击连接按钮开始连接FTP服务器,连接流程图如下图所示. 点击"连接&q ...

  7. spring中使用ftp连接池(ftpClientPool)

    如题,我们在一些项目中可能会涉及到ftp上传.下载客户资料.附件.但是若每次上传或下载时都去创建一次ftp连接,上传(  下载)一个文件再关闭,则太耗费连接资源,这时候可以考虑使用连接池(就如同我们需 ...

  8. php连接ftp实例,PHP_php建立Ftp连接的方法,本文实例讲述了php建立Ftp连接 - phpStudy...

    php建立Ftp连接的方法 本文实例讲述了php建立Ftp连接的方法.分享给大家供大家参考.具体分析如下: 今天看了下ftp函数,总结一下: FTP相关函数: ftp_connect(host,par ...

  9. FTP连接和推送工具

    /*** ftp连接和推送工具*/ public class FTPConnectionTool {/*** 获取FTPClient对象* * @param ftpHost 服务器IP* @param ...

最新文章

  1. (C++)1036 跟奥巴马一起编程
  2. java常用注解汇总_Spring常用注解汇总
  3. 从底层理解Python的执行
  4. 《数据结构与算法分析:C语言描述》复习——第六章“排序”——基数排序
  5. javascript判断ie浏览器
  6. 这样给面试官解释约瑟夫环问题的几种巧妙解法,面试官满意的笑了
  7. C语言stdio.h与stdlib.h的区别
  8. Office合并字符功能比较(转)
  9. 苹果AirPods 2新爆料:无线充电盒重量增加 支持快速充电
  10. String*Buffer*Builder理解
  11. [洪流学堂]Hololens开发入门篇1之模拟器开发环境配置
  12. EShop网上商城项目(二)
  13. AD的命名规则 AD常用产品型号命名规则
  14. swiper 定义放多少张图片_小程序瀑布流组件:支持翻页与图片懒加载
  15. 与你邂逅——软件工程
  16. 物理学 第六版 上册、下册 课后答案 东南大学 马文蔚
  17. margin 百分比是按参照物来计算滴 不知道吧?
  18. 7-13 大家一起来玩游戏 (20 分)
  19. STM32学习手记5 BKP后备寄存器、RTC和中断
  20. POI解析Word批注信息

热门文章

  1. 要素集获取要素_Excel点文件转面要素
  2. Spring入门-框架搭建
  3. SpringCloud04 服务配置中心、消息总线、远程配置动态刷新
  4. English trip -- VC(情景课)4 A Health
  5. java并发编程(更新)
  6. 对大文件进行只打印过滤条件到列表元素(优化)
  7. Android studio每次启动卡在fetching Android sdk compoment information的解决方案
  8. ArcMAP获取要素的外包多边形
  9. 获取到某一方法的调用者的类名、方法名、命名空间
  10. 生态功能区划方法之三:聚类分析法和生态融合法