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

今天在写代码而后调试的时候发现了这个问题。html

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

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

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

ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

并无什么用。由于原来这段代码就加上了啊。缓存

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

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

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

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

而为何加上后缀名,就不会发生这种替换,并不清楚,我很懒,还但愿能有高手帮忙解释一下。优化

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

2016-08-25 补充

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

2016-10-17 补充

        今天发现,貌似这个跟操做系统有关系,老的测试环境(RedHat)上面就算使用了 8 月 25 号的方法也会出现图片文件中字节位被替换成 ‘0D’ 的现象,但是生产上面(CentOS)是没有问题的。

相关文章
相关标签/搜索