我正在尝试实现文件存储队列子系统,如wwdc 2012带块的异步设计模式,GCD和XPC中所述。我有一个自定义并发处理队列,它格式化数据并将结果移交给我的自定义并发存储队列。然后,存储队列创建一个dispatch_io_t通道进行写入,拆分文件(如果我不拆分文件,我会得到大数据的内存问题),并使用dispatch_io_write写入每个块。有时写入完成没有错误,但我经常为任何一个块获得EFAULT
或EDESTADDRREQ
我的一般方法概述如下:
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
,如果是,dispatch_io_barrier
频道或队列的dispatch_barrier_async
?
3.在这种情况下,我是否应该注意任何通道标志?
答案 0 :(得分:0)
我的代码段中没有看到任何明显错误的内容。应该不需要手动分块数据并提交多个写操作(调度IO已经在内部更有效地执行此操作),并且我从未听说过之前遇到的那些特定IO错误。
请使用可再现问题的可运行测试用例提交bug report。
答案 1 :(得分:0)
如果使用DISPATCH_IO_STREAM标志创建基于流的通道,不支持随机访问,则忽略任何偏移值(currentOffset),并将数据写入当前文件位置(在您的代码段中为0),如所述{{ 3}}