FTP文件传输协议
文件传输协议FTP(File TransferProtocol)是因特网中使用最广泛的文件传输协议。FTP使用交互式的访问,允许客户指定文件的类型和格式(如指明是否使用ASCII码),并允许文件具有存取权限(如访问文件的用户必须经过授权,并输入有效的口令)。
文件传输协议有基于TCP的FTP和基于UDP的简单文件传输协议TFTP,它们都是文件共享协议中的一大类,即复制整个文件,其特点是:若要存取一个文件,就必须先获得一个本地的文件副本。如果要修改文件,只能对文件的副本进行修改,然后再将修改后的文件传回到原节点。
FTP工作在TCP/IP模型的应用层,基于的传输协议是TCP,FTP客户端和服务器之间的连接是可靠的,面向连接的,为数据的传输提供了可靠的保证。在FTP客户机与服务器之间,采用来了两条TCP连接,这两条连接分别是控制连接和数据连接。在控制连接过程中,FTP服务器使用的端口号为21,在数据连接过程中,FTP服务使用的端口号为20,而客户机在整个过程中使用的端口号都是临时端口号,这两个临时端口号可以相同,也可以不同,当然在绝大多数情况下,这两个临时端口号都是不同的。在整个从连接的发起到数据传输的整个过程中,控制连接一直都打开着,而数据连接则在数据开始传送时打开,数据传送完毕后关闭。
控制连接
控制连接的打开与关闭过程如下:
1.服务器在熟知端口21发出被动打开命令,等待客户;
2.客户使用临时端口发出主动打开;
3.当客户不再使用该控制连接时,主动关闭该控制连接。所以整个控制连接过程中,客户始终是控制连接的发起者和终止者。要实现以上控制连接上的通信,客户需要向FTP服务器发送命令,而FTP服务器向客户发送对这些命令的响应来共同完成,即命令是从客户向服务器发送的,而响应则是从服务器向客户机发送。
数据连接
数据连接主要有三个目的:
(1)客户向服务器发送一个文件。(叫作写文件或存储文件)
(2)服务器向客户发送一个文件。(叫作读文件)
(3)服务器向客户发送文件或目录列表。(列出文件名)
数据连接的打开与关闭一般过程如下:
1.客户在控制连接的过程中,通过发送port命令,将客户的IP地址和将在数据连接阶段使用的客户端的临时端口号发送给服务器的控制端口号21后,客户端的数据连接临时端口号处于被动打开的状态。
2.服务器通过数据连接端口号20,利用客户端给出的临时端口号向客户端主动打开命令,于是便打开了此数据连接,与客户端进行数据交换。
3.当服务器不再与客户机进行数据交换后,服务器便主动关闭同客户端的数据连接。
FTP文件夹监接口听功能实现可配置方式(FTP文件夹周期性检测时间可配置,监听地址可配置,本地缓存目录可配置)完成,项目部署后自动执行,当监听到接口文件产生后缓存到本地(缓存到本地需保证上传到FTP的文件已上传完毕,文件完成,防止缓存时文件还未上传完毕),解析接口信息进行流程调度,反馈外部系统回执信息。
功能代码实现使用的sun包ftp工具类
Ø 配置方式实现FTP文件夹监听功能(配置文件路径:conf\monitor.properties)
#周期性检测扫描时间(ms)
monitor_time=5000
#监测的FTP文件夹所在IP
monitor_ip=192.168.1.122
#监测的FTP文件夹所在端口
monitor_port=21
#监测的FTP文件夹所在用户名
monitor_user=develop
#监测的FTP文件夹所在密码
monitor_pwd=123456
#缓存本地文件夹位置
monitor_localpath=E:/ftpmonitor/
#监测的FTP文件夹名称
monitor_serverpath=/flow
#接口文件监听后是否需要删除
monitor_deleteflag=false
Ø 项目启动后FTP文件监听功能自动执行,配置服务器启动后执行监听功能
1) 配置项目部署后服务启动执行程序FtpFileListener
2) 配置启动后执行程序FTP文件夹监听器功能执行FtpFileMonitor.satrt()
3) FTP文件缓存本地时需要检测文件是否已经上传完毕,可通过文件状态识别
FTP监听文件函数
返回值 |
函数 |
参数 |
参数说明 |
函数说明 |
Boolean true:FTP远程文件缓存本地成功false:失败 |
downLoadMonitorDirectory |
remoteDirectory:String |
ftp远程文件夹名 |
ftp文件缓存本地目录 |
localDirectoryPath:String |
本地缓存文件夹 |
|||
deleteFlag:boolean |
缓存本地后是否需要删除 |
|||
Start:Date |
缓存开始时间,超时处理判定 |
/**
*
* @param remoteDirectory
* 远程文件夹(ftp)
* @param localDirectoryPath
* (缓存本地路径)
* @param deleteFlag
* (是否删除该文件夹下所有文件)
* @param start
* 文件下载耗时开始时间戳
* @return (true/false)
* @throws FtpProtocolException
*/
public boolean downLoadMonitorDirectory(String remoteDirectory, String backPath, String localDirectoryPath,
Date start) {
try {
System.out.println("ftp监听文件----开始!");
String fileName = new File(remoteDirectory).getName();
Iterator
while (allFile.hasNext()) {
FtpDirEntry file = allFile.next();
String name = file.getName();
// 递归下载FTP多层文件夹下的内容
String type = file.getType().name();
if ("DIR".equals(type)) {
String strremoteDirectoryPath = remoteDirectory + "\\" + name;
downLoadMonitorDirectory(strremoteDirectoryPath, backPath, localDirectoryPath, start);
} else {
String newName = ".." + backPath + name;
long preLoadSize = file.getSize();
System.out.println("ftp监听到的文件大小preLoadSize : " + preLoadSize);
Thread.sleep(500L);
long afterLoadSize = this.ftpClient.getSize(file.getName());
System.out.println("1s 后ftp监听到的文件大小afterLoadSize : " + afterLoadSize);
boolean flag = checkFtpFileStatus(file, preLoadSize, afterLoadSize, start);
int index = name.lastIndexOf(".");
String preFixName = name.substring(0, index);
String suffixFileType = name.substring(index+1, name.length());
if (flag) {
//校验文件类型
boolean vaflag = validateFileType(suffixFileType);
if(vaflag){
System.out.println("缓存ftp 监控文件 :" + name +"到本地路径开始!");
download(remoteDirectory + File.separator + name, localDirectoryPath + File.separator + name);
System.out.println("缓存ftp 监控文件 :" + name +"到本地路径结束!");
try {
ftpClient.deleteFile(newName);
} catch (Exception e) {
}
}
System.out.println("备份ftp 监控文件 :" + name +"到ftp 备份路径开始!");
ftpClient.rename(file.getName(), newName);
System.out.println("备份ftp 监控文件 :" + name +"到ftp 备份路径结束!");
} else {
}
}
}
} catch (Exception e) {
System.err.println("监听报错: " + e.getMessage());
return false;
}
System.out.println("ftp监听文件----结束!");
return true;
}
文件状态监测
返回值 |
函数 |
参数 |
参数说明 |
函数说明 |
Boolean, True:ftp接口文件上传成功 False:ftp接口文件上传失败 |
checkFtpFileStatus |
File:FtpDirEntry |
Ftp文件流对象 |
检测接口文件是否已经是上传完毕的 |
preLoadSize:Long |
检测文件大小参照数值 |
|||
afterLoadSize:Long |
检测文件大小参照数值(一段时间后) |
|||
Start:Date |
缓存开始时间,超时处理判定 |
}