您的位置:首页 > 编程语言 > PHP开发

有意思,使用FtpClient上传文件,上传后的文件总是会莫名奇妙的变大

2016-06-30 22:34 323 查看
今天在写代码然后调试的时候发现了这个问题。

代码主要是从手机上选择照片上传到服务端,具体实现逻辑中,服务端会先将上传请求中的文件数据放到服务端机器的缓存目录,然后再从缓存目录挪到另外一台FTP服务其中。

测试的时候发现,将在Android机器上选择并上传到FTP服务器的文件再从FTP服务器上下载下来,加上原来的扩展名(在强迫证的驱使下,我统一了上到FTP服务器的文件的命名,全部用数据库生成的唯一主键,前缀年月日,一共16位数字,问题就出在这儿),在windows上尝试用照片查看器打开,会提示文件已损坏。而在iOS机器上选择并上传到FTP服务器上的相同一张照片文件(jpg)格式的,重新从FTP服务器上面下载下来,尽管能用windows上的照片查看器打开,但照片显示的一团糟,开始感觉很诡异。

上网查了下使用commons-net-2.0.jar包中的FtpClient类上传文件变大的问题,普遍的答案是要加上如下一行代码:

ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

并没有什么用。因为原来这段代码就加上了啊。

为这个问题折腾了一天啊!!!

最后,多亏了二进制文件对比工具的帮忙,发现在16进制视图下面,源文件跟FTP上面down下来的文件相比,后者将前者很多空位替换成了“0D”(我百度了一下,0D貌似代表的是回车符号),这样就解释了为什么上传的文件打开会出问题,而且空位占的空间比0D符号要小得多,这种替换会导致上传的文件越大,源文件跟上传之后的文件大小差异越大。



还有就是,同样一张照片,从Android上传的再下载下来打开会报错,但从iOS上传的再下载下来确仍然可以打开,但现实乱码(色块)。我同样将服务端缓存目录中文件同FTP上下载下来的问价做而十六进制对比,还是只是空位变成了0D符。经过一番折腾,我发现同一张照片文件,iOS机器上的比Android机器上的要大了一些,他们都是从Window上copy过去的,我猜测可能是复制到iOS机器上,iOS系统会自动对图片文件进行优化,这种优化就会导致文件变大一些,好处就是上面提到的空位被0D符号替换并不会造成文件不能打开的问题,具体的原理我就不清楚了。

那么空位被0D替换的问题怎么解决呢?经过n多次尝试,发现只要加上后缀名就好了,也就是说不要将没有后缀名的文件从本机上传到FTP服务器上。应用程序的服务端开在我本机,windows系统,而FTP服务器搭在一台Linux服务器上,兴许是操作系统的差异,导致了二进制文件中某些特殊符号的自动被替换。

而为什么加上后缀名,就不会发生这种替换,并不清楚,我很懒,还希望能有高手帮忙解释一下。

最后由此联想到以前看过的一篇介绍回车和换行历史的文章《回车和换行》,觉得兴许跟这个有关,放到这里备忘。

2016-08-25 补充

今天了解了一种解决办法,那就是先以带后缀的文件名的形式上传到FTP服务器上,然后调用FtpClient的API对已经上传到FTP服务器上面的文件重命名为文件服务器统一的命名格式,这样再下载下来的文件也不会出问题,经过尝试有效。

2016-10-17 补充

今天发现,貌似这个跟操作系统有关系,老的测试环境(RedHat)上面就算使用了 8 月 25 号的方法也会出现图片文件中字节位被替换成 ‘0D’ 的现象,可是生产上面(CentOS)是没有问题的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: