大家好,讨教大家个问题:
使用GCDAsyncSocket从服务器下载文件,怎么拼接NSData数据成为一个文件?
具体情况是这样的——
向服务器发送下载图片命令,然后会回调下面的函数:
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
NSLog(@”接收到的数据为:%@”, data);
使用GCDAsyncSocket从服务器下载文件,怎么拼接NSData数据成为一个文件?
具体情况是这样的——
向服务器发送下载图片命令,然后会回调下面的函数:
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
NSLog(@”接收到的数据为:%@”, data);
//接收数据后还要执行接收方法
[self.socket readDataWithTimeout:-1 tag:APKSokcetReadTag];
}
服务器传输图片时,socket: didReadData: withTag:会调用多次,输出截图如下:
怎么把接收到的NSData数据拼接成一个文件?请大家指点下,谢谢了!
解决方案
5
接收到的数据直接写入文件不就可以了吗?
10
其实你就是想把多个NSData拼接起来吧。
你懒加载一个NSMutableData,然后把接受到的每一个NSData 添加进去:
你懒加载一个NSMutableData,然后把接受到的每一个NSData 添加进去:
- (NSMutableData *)data { if (_data == nil) { _data = [NSMutableData new]; } return _data; }
[self.data appendData:data]
这样的话,是把全部的Data都放在内存里了,假如你的文件会比较大,就像楼上说的,接收一点就写入一点,不用在内存中占用太多空间。
10
didReadData是分段读取的数据。所以正如楼上的做法,先确保你接收到了服务器传递过来的是完整的NSData流,才能保证写入文件时的成功。 NSData 有实例方法 writeToFile:options:error 可以将数据流写入到指定路径的文件,提前是你要知道你接收到的是什么类型的流(图像,文字,音频)。
25
writeToFile: atomically:确实是一次性写入的,你可以采用这种读一点、就写一点的方法:
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:aPath]; [fileHandle seekToEndOfFile]; [fileHandle writeData:[textToWrite dataUsingEncoding:NSUTF8StringEncoding]]; [fileHandle closeFile];