关于iOS中的文件打散与使用FTP上传(伪断点续传大文件)

因为最近要写一个项目,里面考虑到网络的问题,而目前的苹果官方API中的流传输上传文件无法暂停,所以只好把一个文件打散为多份小份的文件,逐个上传到服务器中,再靠服务器合成。若想暂停直接断开传输即可,当后来需要继续传输的时候就会从断开传输的小文件开始接着逐个上传。

为此我写了一个小Demo,包含了文件打散和文件上传,也做了续传的部分。

Demo地址:https://github.com/dark19940411/FTPDemo_OBJC

这篇文章不会讲太多的代码细节,主要讲讲实现的思路。代码细节在我的demo中就可以看到了。

主要的思路:

1、先对完整的大文件做md5校验,然后将校验码写出到txt中保存

这一步的意义在于,让服务端检测上传的小文件有没有数据丢失,或者服务器合成的完整文件有没有不正确。因为md5校验码最后也会上传到服务器中,服务器合成出完整文件后仍然会对整个文件做md5校验,得出的校验码和上传的校验码进行比对。

2、读取文件,将文件打散

这个比较简单,使用NSData把文件以数据流的形式读进来,进而定制一个固定长度,比如5MB就是5*1024*1024,然后逐段逐段地写出这些NSData文件,文件格式并不重要,你可以随意命名,比如”文件名.1“代表了一个”碎块“,以此类推。

说到文件格式,前阵子听一个师兄说的觉得非常有道理,于是在这里记录下来:

-------------------------------------------题外话:文件格式-------------------------------------

所有的文件都是由二进制组成,至于它有什么意义,最后都是由一些规定的协议让计算机对其进行解析得出来的,一串二进制流,为什么给它加个后缀它就可以对应的打开了呢,因为它的头会有一串二进制数字,用来规定了它可以被什么协议解析。学过计算机网络的人可能会比较清楚,当在网络上进行数据传输时,一串二进制数据,在穿过网络的分层结构中的每一层的时候,都会被众多的协议不断的封装(给它加了很多头啊尾啊之类的),于是它最后可以被合理的解析。其他的本地文件也是类似的,pdf,doc,MP3等等,它们都有只是一串二进制串而已,而它们里面的一些头啊尾啊的一些规定规格让他们能被pdf解析器,word,音乐播放器等解析而已。

然后规定这些文件的解析方式的我们可以把他们称成协议,有公有协议(就是全地球都认可可用的),有私有协议(企业内部用的)。对私有协议举个例子,我玩中土世界(一款游戏)的时候,它的文件里面的一些音频格式和CG视频格式,我都没见过,但它能被游戏识别,我觉得这应该就是开发公司内部制定了私有协议吧(这个例子可能不正确,如果有错误希望大家指出并予以更正,主要是为了帮助大家理解)

---------------------------------------------------END-----------------------------------------------

3、FTP 上传

这一点,简单来说就是一个输入流,一个输出流,输入流设定为本地文件,输出流设定为FTP 服务器的地址,并且设定FTP账号和密码就可以了。

NSInputStream,NSOutputStream.

在这里注意一点,你要往服务器里写东西,服务器里的索引必须得存在,因为客户端上传文件到服务器,没办法新建文件夹的。比如"ftp://111.11.111.11/up/file name",那么服务器中的up文件夹必须得存在,否则写出就会出错。

而且在这里要设定两对输入输出流,一对用于文件本身的读入写出,一对用于文件的CRC校验文件的写入写出(其实有了CRC校验,那么前面的MD5作用就是只能用于检验合成是否出错了)

还有,比较容易出错的一点就是,同一对InputStream,OutputStream,一个时间里只能处理一个文件,由于input是对应本地文件的所以速度很快不需要管,主要是OutputStream,在还没写出完成文件时,不要再使用它进行文件传输,等它完成相应stream事件后,你再做处理,否则文件传输就会失败。

最后还有一个叫Reachablity的类文件用来检查网络是否连通,这个类在苹果官网上有得下载,我的demo里也有,百度谷歌必应一下应该也找得到。


4、记录当前已上传的文件数量,并且保存到plist中

这一步是用来断点续传用的,上一次中断了,或者程序重启后,可以从中断的地方开始传输文件。因为碎块文件名的命名格式为”文件名.1“,”文件名.2“……所以只用把文件名和已上传文件数做一个键值存储就可以了。

大致就是这样了,希望这篇文章对你有帮助。


你可能感兴趣的:(iOS开发)