Apache Commons VFS远程服务器内文件复制能否用主机命令替代网络传输?
Apache Commons VFS实现FTP服务器端本地复制
核心结论
Apache Commons VFS本身没有直接封装FTP协议的服务器端复制命令(比如FTP原生的SITE CPFR/SITE CPTO或直接执行cp shell命令),默认的copyFrom方法确实会通过客户端中转数据,导致复制速度较慢。
可行解决方案
1. 直接调用FTP服务器端原生命令
可以通过VFS获取底层的FTPClient实例,发送原生FTP命令实现服务器端本地复制,避免数据中转:
// 假设srcFile和destFile都是FtpFile类型实例 FtpFile srcFtpFile = (FtpFile) srcFile; FtpFile destFtpFile = (FtpFile) destFile; FTPClient ftpClient = srcFtpFile.getFileSystem().getClient(); try { // 尝试使用FTP标准的SITE CPFR/CPTO命令(部分服务器如vsftpd需开启allow_site_cp配置) ftpClient.sendCommand("SITE CPFR", srcFtpFile.getAbsolutePath()); ftpClient.sendCommand("SITE CPTO", destFtpFile.getAbsolutePath()); int reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { throw new IOException("服务器端复制失败,响应码: " + reply); } } catch (IOException e) { // 若SITE命令不支持,尝试通过EXEC命令执行shell的cp命令(需服务器允许执行外部命令) try { ftpClient.execCommand(String.format("cp %s %s", srcFtpFile.getAbsolutePath(), destFtpFile.getAbsolutePath())); int reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { throw new IOException("执行cp命令失败,响应码: " + reply); } } catch (IOException ex) { // 所有服务器端命令都不支持时,退回到原有的copyFrom中转方式 destFile.copyFrom(srcFile, Selectors.SELECT_ALL); } }
注意:这种方式依赖FTP服务器的配置,不同服务器(vsftpd、proftpd等)支持的命令不同,需要提前确认服务器是否允许相关操作。
2. 扩展VFS的FTP文件系统
如果需要更通用的封装,可以自定义FtpFile子类或扩展FtpFileSystem,将服务器端复制逻辑封装成独立方法,方便业务代码调用。
关键注意点
- 服务器端复制的前提是目标FTP服务器支持对应的命令,若服务器未开启相关权限,只能退回到
copyFrom的中转方式。 - 若对灵活性要求较高,也可以考虑直接使用Apache Commons Net的
FTPClient,它对原生FTP命令的支持更直接。
内容的提问来源于stack exchange,提问作者SrGnis
相关产品推荐
相关产品推荐

