2013-01-22 32 views
1

我試圖實現文件存儲隊列子系統,如wwdc 2012異步設計模式與塊,GCD和XPC中所述。我有一個自定義併發處理隊列,用於格式化數據並將結果移交給我的自定義併發存儲隊列。然後,存儲隊列創建一個dispatch_io_t通道用於寫入,分割文件(如果我不分割文件,則會遇到大數據的內存問題),並使用dispatch_io_write寫入每個塊。有時候寫操作完成後沒有出現錯誤,但是,我常常各塊EFAULT或EDESTADDRREQ在GCD隊列中的多個dispatch_io_writes

我一般的做法是列出的任何一個無論是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,如果是,則需要使用dispatch_io_barrier的通道或dispatch_barrier_async的隊列?
3.在這種情況下,我應該注意哪些頻道標誌?

回答

0

我在你的代碼片段中沒有看到任何明顯的錯誤。應該不需要手動分塊數據並提交多個寫入操作(派遣IO已經在內部更有效地完成了這個操作),並且我從來沒有聽說過之前遇到過那些特定的IO錯誤。

請將文件bug report與可重現問題的可運行測試用例一同提交。

0

如果使用DISPATCH_IO_STREAM標誌創建基於流的通道,但不支持隨機訪問,則將忽略任何偏移值(currentOffset),並將數據寫入當前文件位置(在片段中爲0),如this