如果一个文件相对来说比较大的话,一次性读取的话势必会占很大的内存,因此可以考虑分次读取,每次只读取少部分的内容。
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *homePath = NSHomeDirectory();
NSString *srcPath = [homePath stringByAppendingPathComponent:@"src.jpg"];
NSString *descPath = [homePath stringByAppendingPathComponent:@"desc.jpg"];
//打开原文件和目标文件
NSFileHandle *srcHandle = nil;
NSFileHandle *descHandle = nil;
srcHandle = [NSFileHandle fileHandleForReadingAtPath:srcPath];
//获取原文件内容的长度
NSUInteger srcLength = [srcHandle availableData].length;
//设置每次读取的长度
NSInteger len = 5000;
for (int i = 0; i <= srcLength/len+1; i++) {//加1是因为第一次运行的时候只是创建了文件,并没有复制数据
descHandle = [NSFileHandle fileHandleForReadingAtPath:descPath];
if (descHandle) {//如果有目标文件,则复制剩下的内容
//获取目标文件内容的长度
NSUInteger descLength = [descHandle availableData].length;
if (descLength < srcLength) {//如果目标文件比原文件内容少,则说明还没有复制完成,继续进行复制操作
//由打开供读取变成打开供更新
descHandle = [NSFileHandle fileHandleForUpdatingAtPath:descPath];
//设置要读取的偏移量为目标文件的长度,就是要从什么位置开始读取
[srcHandle seekToFileOffset:descLength];
NSData *remainContent = [[NSData alloc] init];
//读取文件的内容(因为前面设置好了偏移量,因此这里读取数据的内容为偏移量之后到末尾的内容)
if (srcLength - descLength > len) {//如果剩下的长度大于500,则读取500字节
remainContent = [srcHandle readDataOfLength:len];
} else {//如果剩下的长度小于500,则读取剩下的长度内容即可
remainContent = [srcHandle readDataOfLength:(srcLength - descLength)];
}
//偏移量设置为目标文件的最后,要不然会覆盖原来的内容
[descHandle seekToEndOfFile];
//写数据
[descHandle writeData:remainContent];
NSLog(@"已经写入数据大小:%ld",descLength+remainContent.length);
} else {
NSLog(@"文件复制完成!");
break;
}
} else {//如果没有目标文件,则创建目标文件,并且复制指定的内容到里面去
NSLog(@"===生成目标文件===");
//创建文件管理器
NSFileManager *fileManager = [NSFileManager defaultManager];
//创建目标文件
BOOL success = [fileManager createFileAtPath:descPath contents:nil attributes:nil];
if (success) {
NSLog(@"Desert File Create Success!");
} else {
NSLog(@"Desert File Create Failure!");
}
}
}
[srcHandle closeFile];
[descHandle closeFile];
}
return 0;
}
这里可能只考虑到一部分优化,希望朋友们发现有其他的方法也可以提出来讨论讨论,谢谢!