用NSFileHandle实现每次定量读取一个大文件

如果一个文件相对来说比较大的话,一次性读取的话势必会占很大的内存,因此可以考虑分次读取,每次只读取少部分的内容。

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;
}

这里可能只考虑到一部分优化,希望朋友们发现有其他的方法也可以提出来讨论讨论,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值