1

我正在尝试实现文件存储队列子系统,如 wwdc 2012 Asynchronous Design Patterns with Blocks、GCD 和 XPC 中所述。我有一个自定义并发处理队列,用于格式化数据并将结果移交给我的自定义并发存储队列。然后存储队列创建一个dispatch_io_t通道用于写入,拆分文件(如果我不拆分文件,我会遇到大数据的内存问题),并使用dispatch_io_write写入每个块。有时写入完成没有错误,但通常我得到任何一个块EFAULTEDESTADDRREQ任何一个块

我的一般方法概述如下:

dispatch_async(processingQueue, ^{

// prepare dispatch data for storageQueue

dispatch_async(storageQueue, ^{

    dispatch_io_t writeChannel = dispatch_io_create_with_path(DISPATCH_IO_STREAM,
                                                              [pathString UTF8String],
                                                              O_RDWR|O_CREAT, // read-write, create if not exist
                                                              S_IRWXU|S_IRWXG|S_IRWXO, // set all permissions
                                                              storageQueue,
                                                              ^(int error) {

                                                              });

    __block size_t chunkSize = STORAGE_WRITE_CHUNK_SIZE;

    __block off_t currentOffset = 0;

    dispatch_io_set_high_water(writeChannel, chunkSize);

    for (currentOffset = 0; currentOffset < imageDataSize; currentOffset += chunkSize) {

        // is dispatch_barrier required?
        dispatch_data_t blockData = dispatch_data_create_subrange(dictData,
                                                                  currentOffset,
                                                                  MIN(imageDataSize - currentOffset,chunkSize));


        if (dispatch_data_get_size(blockData) > 0) {

            dispatch_io_write(writeChannel,
                              currentOffset,
                              blockData,
                              storageQueue,
                              ^(bool done, dispatch_data_t data, int error){

                              });

        } else {

            NSLog(@"Error chunking data for writing!!");
            break;

        }
    }

    dispatch_io_close(writeChannel,0);
});
});

我尝试过使用串行队列,包装在dispatch_barrier块中,修改dispatch_io channel标志,但问题仍然存在 -dispatch_io_write由于地址或目的地错误而经常出错

希望得到一些答案:
1. 使用dispatch_io_write自定义并发队列进行缓冲文件写入的推荐方法是什么?
2. 我是否需要使用频道或队列dispatch_barrier,如果需要,是否需要? 3. 在这种情况下,我应该注意哪些频道标志?dispatch_io_barrierdispatch_barrier_async

4

2 回答 2

0

如果使用 DISPATCH_IO_STREAM 标志创建不支持随机访问的基于流的通道,则会忽略任何偏移值 (currentOffset),并将数据写入当前文件位置(代码段中的 0),如此描述

于 2014-07-22T08:35:00.980 回答
0

我在您的代码段中没有看到任何明显错误。应该不需要手动分块数据并提交多个写入操作(dispatch IO 已经在内部更有效地执行此操作),而且我以前从未听说过遇到这些特定的 IO 错误。

请提交带有重现问题的可运行测试用例的错误报告。

于 2013-01-24T02:42:32.593 回答