专栏首页LeoXu的博客有意思,使用FtpClient上传文件,上传后的文件总是会莫名奇妙的变大

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

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

代码主要是从手机上选择照片上传到服务端,具体实现逻辑中,服务端会先将上传请求中的文件数据放到服务端机器的缓存目录,然后再从缓存目录挪到另外一台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)是没有问题的。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [翻译]Android教程-保存数据-保存键值对

    http://developer.android.com/training/basics/data-storage/index.html

    LeoXu
  • [翻译]Android教程-保存数据-支持多种语言

    为了添加对更多语言的支持,就要在res/里面另外再创建包含一个其路径名称的末尾带上连字符后面,再跟上ISO语言编码的 values 路径 . 例如,value...

    LeoXu
  • 使用for循环对 golang 中结构体数组取值进行修改时,需要注意的问题

    LeoXu
  • 怎么用FTP软件将wordpress网站文件上传到Web服务器?

    WordPress建站,必须要把wordpress网站文件上传到Web服务器,其实做站都必须要用到FTP软件。

    用户7261497
  • 【RL-TCPnet网络教程】第35章 FTP文件传输协议基础知识

    本章节为大家讲解FTP(File Transfer Protocol,文件传输协议)的基础知识,方便后面章节的实战操作。

    armfly
  • 在IIS上搭建多用户隔离的FTP服务

    FTP是文件传输协议(File Transfer Protocol)的简称,该协议属于应用层协议(端口号通常为20、21),用于Internet...

    .Net框架学苑
  • 向服务器上传文件的利器

    近来有朋友问我说,如何将windows上的文件上传到Linux服务器上? 上传到VMware 安装的虚拟机上?

    DataScience
  • 分布式监控系统SkyWalking

    SkyWalking 是针对分布式系统的应用性能监控,天生吻合微服务、云原生和面向容器的分布式系统架构。PHP应用也可接入,但需以插件方式接入,偶尔也会有一些坑...

    运维部落
  • HDUOJ-------单词数

    单词数 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/...

    Gxjun
  • Windows核心编程:第9章 用内核对象进行线程同步

    https://github.com/gongluck/Windows-Core-Program.git

    gongluck

扫码关注云+社区

领取腾讯云代金券