Java -- 大文件分片上传后台的处理
问题:
js上传文件时文件太大导致的上传失败,到底多大会上传失败没测试过(因为我测试上传了一个10G文件失败了)。原因猜测很多,可能和post之类的网络协议有关,可能和后台某些设置有关。
思路:
思路挺简单的,因为前台上传使用的 Web Uploader,一个百度的插件,文档里清清楚楚写着有一个multiple属性,设置成true开启分片上传,听名字就知道可以用来上传大文件,我想断点续传之类的应该都是用这个做的吧。嘛,我的需求没那么复杂,能上传就行。然后重点是后台。
分片上传后台的接收,网上很多帖子的做法是用RandomAccessFile获取到文件,然后把文件下标(不知道怎么形容好)移到文件最后,然后把分片上传的数据写入到后面。
然后我遇见的问题有两个,一个一个遇见的。。1.分片上传他是速度很快的发送数据,然后tomcat应该会为每个请求分配不同的线程,所以有多线程问题(比如第一个请求正在写数据还没写完第二个请求就把文件拿过去接着写了)。2.分片上传因为是请求,所以顺序是不能保证的,每次都在文件最后开始写入会出现文件损坏。(eg:一个文件叫做"123",现在把文件拆分成"1","2","3"。分三次请求发送给服务器,服务器的接收顺序可能是321,132。这样会造成文件损坏)。
解决:
问题1:一开始在网上找资料发现有个叫文件锁的东西可以用,可是报了一个错,网上管管这个错误是因为线程一获取了文件锁,在线程一没有释放的时候线程二去获取这个锁就会抛出异常。囧。我理解的锁难道不该是线程二没获取到锁应该就等着线程一释放再去获取嘛,直接抛出异常是什么鬼。嘛,不想这么多,直接给拼接方法那里加个 synchronized 关键字就好了。这样大小起码看起来是正常了(虽然这样做并没有什么卵用)。
问题2:这个是最蛋疼的,测试的时候发现压缩包文件在这样上传后会出现文件损坏,想了很久还是经过同事提醒才认识到这个问题。知道问题,思路就可以有很多了,位置不对放对位置就好了嘛。我的思路是多看了下uploader这个插件,分片上传时给把文件大小,分片总数,当前分片数都传给你。然后根据这个些参数在设置文件大小,根绝当前分片数移动到对应位置写入数据就好了。这样写上边问题1加上的 synchronized 关键字去掉也可以。
因为代码直接复制过来都没格式了。所以就简单说下问题和思路。看以后会不会有空再贴代码咯。