使用Apache从FTP下载数据截断

时间:2018-03-21 19:54:00

标签: java apache file ftp ftp-client

使用commons-net:commons-net:3.6中的Apache FTP客户端,我正在使用

从我们的FTPS服务器读取文件
FTPClient#retrieveFile("/OUT/somefile.xml", someBAOS)

通常情况下,一切都运行良好,但有时文件会被截断。

当一切正常时,这是协议:

< 220 ProFTPD 1.3.5a Server (someserver) [::ffff:...]
> AUTH TLS
< 234 AUTH TLS successful
> PBSZ 0
< 200 PBSZ 0 successful
> PROT P
< 200 Protection set to Private
> USER someuser
< 331 Password required for someuser
> PASS ***
< 230 User someuser logged in
> TYPE I
< 200 Type set to I
> PASV
< 227 Entering Passive Mode (...).
> RETR /OUT/somefile.xml
< 150 Opening BINARY mode data connection for /OUT/somefile.xml (4769503 bytes)
< 226 Transfer complete

当文件被截断时,会记录较小的大小:

< 150 Opening BINARY mode data connection for /OUT/somefile.xml (2569402 bytes)

截断偶尔发生。在下一次下载,一小时后,一切都很好。我们非常确定该文件在此期间没有变化。

日志文件是使用SocketClient#addProtocolCommandListener生成的,我很确定更改的大小不是来自我的监听器。我猜,文本是由FTP服务器生成的,并按原样转储。 有人可以确认文件大小确实来自服务器(而不是由Apache客户端添加)吗?

有趣的是,下载的截断文件有2602133个字节(我很确定,没有\r通过文本转换或类似添加;第一,我们进行转换;其次,差异是31371字节和那里有56577条线。)

最可能的解释是有人在此期间更改文件,但服务器日志清楚地说明当时没有其他人。

任何想法如何找出发生了什么?

结果

我还有更多日志清楚地显示问题发生时上传 。同时,日志声称没有时间重叠。无论如何,确认150 ...行直接来自服务器,毫无疑问并发访问是罪魁祸首。

2 个答案:

答案 0 :(得分:2)

消息

/usr/lib/phoenix/bin/sqlline.py HOSTNAME.RealmName:2181:/hbase-secure:hbase/HOSTNAME.RealmName@RealmName:/etc/hbase.keytab

来自服务器,即服务该文件的服务器只能看到长度为2569402字节的文件。最可能的原因 - 在不知道此处涉及的实际系统的情况下 - 是您当前创建的尝试下载的文件。这就是为什么它在几分钟后工作的原因,因为文件创建完成了。

这是不同解决方案的常见问题:

  • 创建一个具有已定义前缀或后缀的同名锁文件,您可以检查该文件是否存在,只有在不存在的情况下才执行下载。
  • 检查尺寸一段时间,如果尺寸没有改变一段时间,则只尝试下载。
  • 使用临时名称或其他目录创建文件,并将其重命名/移动到目标名称和目的地

正如我所说,我不认为这对您的客户来说是一个问题,服务器显然报告错误的长度,因此问题的原因必须在那里。

答案 1 :(得分:2)

在建立数据连接之后,即在数据传输开始时,服务器立即发送150 Opening...消息。这意味着当数据传输开始时,消息包含从服务器角度看的文件大小。这意味着文件在传输过程中不会被截断,而是比您在服务器端已经预期的要小。

由于使用二进制模式,因此不会在服务器端更改行结束。鉴于您获得的实际下载大小比服务器报告的大,但小于您的预期,在下载运行时可能会在服务器端更改文件。