dispatch_io

1、文件支持顺序读取和并列读取

2、文件的读取最好指定读取的最小值和最大值

 

假设有如下的获取文件

NSString* getFileName() {
    NSString* desktop = @"/Users/cy_k_yc/Desktop";
    NSString* path = [desktop stringByAppendingPathComponent:@"configuration_beauty_5.plist"];
    
    return path;
}

 

如下是顺序读取文件的方法:

复制代码
void testDispatchIOSerial() {
    NSString* path = getFileName();
    // 创建一个serial 的线程队列
    dispatch_queue_t queue = dispatch_queue_create("myio", NULL);
    dispatch_fd_t fd = open(path.UTF8String, O_RDONLY, 0);
    dispatch_io_t io = dispatch_io_create(DISPATCH_IO_STREAM, fd, queue, ^(int error) {
        close(fd);
    });
    
    // 指定了每次读取最小和最大的文件大小
    size_t water = 1024;
    dispatch_io_set_low_water(io, water);
    dispatch_io_set_high_water(io, water);
    long long totalSize = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:NULL].fileSize;
    NSMutableData* mutableData = [[NSMutableData alloc] init];

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    dispatch_io_read(io, 0, totalSize, queue, ^(bool done, dispatch_data_t  _Nullable data, int error) {
        if (error == 0) {
            size_t size = dispatch_data_get_size(data);
            if (size > 0) {
                [mutableData appendData:(NSData *)data];
            }
        }
        
        if (done) {
            NSString* result = [[NSString alloc] initWithData:mutableData encoding:NSUTF8StringEncoding];
            NSLog(@"%@", result);
            close(fd);

            dispatch_semaphore_signal(semaphore);
        }
    });
    
    dispatch_time_t till_time = dispatch_time(DISPATCH_TIME_NOW, 1ull * NSEC_PER_SEC);
    dispatch_semaphore_wait(semaphore, till_time);
}
View Code
复制代码

如上代码所示,使用的是线程队列

 

 

如下是并列读取的方式,可以加快读取文件的数据;如果文件比较大的时候,该方法是相对比较好的方式

复制代码
void testDispatchIOConCurrent() {
    NSString* path = getFileName();
    dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_fd_t fd = open(path.UTF8String, O_RDONLY, 0);
    dispatch_io_t io = dispatch_io_create(DISPATCH_IO_STREAM, fd, queue, ^(int error){
        close(fd);
    });
    
    size_t water = 1024;
    dispatch_io_set_low_water(io, water);
    dispatch_io_set_high_water(io, water);
    
    long long totalFileSize = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:NULL].fileSize;
    // 先申请文件的长度的空间
    NSMutableData* mutableData = [[NSMutableData alloc] initWithLength:totalFileSize];
    dispatch_group_t group = dispatch_group_create();
    for (long long offset = 0; offset < totalFileSize; offset += water) {
        dispatch_group_enter(group);
        // 通过分段读取的方式
        dispatch_io_read(io, offset, water, queue, ^(bool done, dispatch_data_t  _Nullable data, int error) {
            if (error == 0) {
                size_t len = dispatch_data_get_size(data);
                if (len > 0) {
                    const void* bytes = NULL;
                    // 这里的data是分段读取到的数据,通过该函数的映射之后,可以返回新的data,bytes指向的是新data的指针,len也是对应新data的长度
                    dispatch_data_create_map(data, &bytes, &len);
                    [mutableData replaceBytesInRange:NSMakeRange(offset, len) withBytes:bytes length:len];
                }
            }
            
            if (done) {
                dispatch_group_leave(group);
            }
        });
    }
    
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    dispatch_group_notify(group, queue, ^{
        NSString* data = [[NSString alloc] initWithData:mutableData encoding:NSUTF8StringEncoding];
        NSLog(@"%@", data);
        dispatch_semaphore_signal(semaphore);
    });
    dispatch_time_t till_time = dispatch_time(DISPATCH_TIME_NOW, 1ull * NSEC_PER_SEC);
    dispatch_semaphore_wait(semaphore, till_time);
}
View Code
复制代码

 

posted @   LCAC  阅读(148)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示