GCD学习之——Dispatch I/O

来源:互联网 发布:安卓机推荐2017 知乎 编辑:程序博客网 时间:2024/04/27 15:45

Dispatch I/O
在读取较大文件时,如果将文件分成合适的大小并使用Global Dispatch Queue并列读取的话,应该会比一般的读取速度快不少。现今的输入/输出硬件已经可以做到一次使用多个线程更快地并列读取了。能实现这一功能的就是Dispatch I/O和Dispatch Data。
通过Dispatch I/O读写文件时,使用Global Dispatch Queue将一个文件按大小read/write。

dispatch_async(queue,^{/*读取     0~8191字节*/});dispatch_async(queue,^{/*读取  8191~16383字节*/});dispatch_async(queue,^{/*读取 16384~24575字节*/});dispatch_async(queue,^{/*读取 24576~32767字节*/});dispatch_async(queue,^{/*读取 32768~40959字节*/});dispatch_async(queue,^{/*读取 40960~49151字节*/});dispatch_async(queue,^{/*读取 49152~57343字节*/});dispatch_async(queue,^{/*读取 57344~65535字节*/});

可像这样,将文件分割为一块一块地进行读取处理。分割读取的数据通过使用Dispatch Data可更为简单地进行结合和分割。
以下为苹果中使用Dispatch I/O和Dispatch Data的例子

pipe_q = dispatch_queue_create("PipeQ",NULL);pipe_channel = dispatch_io_create(DISPATCH_IO_STREAM,fd,pipe_q,^(int err){   close(fd);});*out_fd = fdpair[i];dispatch_io_set_low_water(pipe_channel,SIZE_MAX);dispatch_io_read(pipe_channel,0,SIZE_MAX,pipe_q, ^(bool done,dispatch_data_t pipe data,int err){   if(err == 0)     {       size_t len = dispatch_data_get_size(pipe data);       if(len > 0)       {          const char *bytes = NULL;          char *encoded;          dispatch_data_t md = dispatch_data_create_map(pipe data,(const void **)&bytes,&len);          asl_set((aslmsg)merged_msg,ASL_KEY_AUX_DATA,encoded);          free(encoded);          _asl_send_message(NULL,merged_msg,-1,NULL);          asl_msg_release(merged_msg);          dispatch_release(md);       }      }      if(done)      {         dispatch_semaphore_signal(sem);         dispatch_release(pipe_channel);         dispatch_release(pipe_q);      }});

以上摘自Apple System Log API用的源代码。dispatch_io_create函数生成Dispatch I/O,并指定发生错误时用来执行处理的Block,以及执行该Block的Dispatch Queue。dispatch_io_set_low_water函数设定一次读取的大小(分割大小),dispatch_io_read函数使用Global Dispatch Queue开始并列读取。每当各个分割的文件快读取结束时,将含有文件块数据的Dispatch Data传递给dispatch_io_read函数指定的读取结束时回调用的Block。回调用的Block分析传递过来的Dispatch Data并进行结合处理。
如果想提高文件读取速度,可以尝试使用Dispatch I/O.

1 0