NSFileHandle拷贝大文件+多线程

//1、要分次读取,分次写入
//2、最后要刷新缓冲区
    
     NSString *docpath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
     NSString *sourceFile = [docpath stringByAppendingPathComponent:@"Xcode_6.4.dmg"];
     NSString *destFile =[docpath stringByAppendingPathComponent:@"Xcode_6.4.dmg.copy"];
    //获得全局队列dispatch_get_global_queue
    //1、优先级
    //2、保留字段 默认为0
    
    __weak ViewController* weakSelf = self;

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
        
        NSFileHandle *srcFdh = [NSFileHandle fileHandleForReadingAtPath:sourceFile];
        //创建文件
        [[NSFileManager defaultManager] createFileAtPath:destFile contents:nil attributes:nil];
        
        NSFileHandle *destFdh = [NSFileHandle fileHandleForWritingAtPath:destFile];
            
            long long filesize = [srcFdh seekToEndOfFile];
            //还得复位到头指针
            [srcFdh seekToFileOffset:0];
            
            NSLog(@"文件的总长度:%llu",filesize);
            
            dispatch_sync(dispatch_get_main_queue(), ^
            {
                [weakSelf.progressbar setHidden:NO];
            });
            
            NSLog(@"currentThread:%@",[NSThread currentThread]);

 //注意:在子线程中需要重新开启自动释放池,否则会造成内存泄露
            //一般在方法返回对象时会产生 return  [obj autorelease];
            //而autorelease 需要借助外部的自动释放工具NSAutoReleasePool  drain 方法来释放所有标识过autorealse的对象
            //如果对象要纳入autoreleasepool 自动释放,需要将对象的申请(产生)和释放都放在autorelease作用域中
                NSData *buffer =nil;

                while (YES)
                {
                    @autoreleasepool
                    {
                        //对象获取要放在自动释放池内。
                        buffer = [srcFdh readDataOfLength:4096*2];
                        if (buffer.length == 0)
                        {
                            break;
                        }
                        //写入数据
                        [destFdh writeData:buffer];
                        buffer = nil;//提前告知ARC,请给我加一个release方法
                    }
                    //计算进度
                    //注意:一定要将整形转换为Float再进行计算
                    float progress = ((float)destFdh.offsetInFile/filesize) ;
                    //如果要减少进度的更新,可以将进度值放大一点
                    NSInteger i = (NSInteger)(progress *1000) %10 ;
                    if (i==0)
                    {
                        //NSLog(@"进度更新..%f",progress);
                        dispatch_async(dispatch_get_main_queue(), ^
                        {
                            [weakSelf.progressbar setProgress:progress];
                        });
                    }
                    //能减少CPU的占用
                   // [NSThread sleepForTimeInterval:0.0001];
                }
                        //刷新缓冲
            [destFdh synchronizeFile];
            
            NSLog(@"拷贝文件成功!");
        }
        [srcFdh closeFile];
        [destFdh closeFile];
});


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值