Пример #1
0
     private static void PatchWithBlocklist(LocalRestoreDatabase database, BlockVolumeReader blocks, Options options, RestoreResults result, byte[] blockbuffer)
     {
         var blocksize = options.Blocksize;
         var updateCounter = 0L;
         using(var blockmarker = database.CreateBlockMarker())
         {
             foreach(var restorelist in database.GetFilesWithMissingBlocks(blocks))
             {
                 var targetpath = restorelist.Path;
                 result.AddVerboseMessage("Patching file with remote data: {0}", targetpath);
                 
                 if (options.Dryrun)
                 {
                     result.AddDryrunMessage(string.Format("Would patch file with remote data: {0}", targetpath));
                 }
                 else
                 {
                     try
                     {   
                         var folderpath = m_systemIO.PathGetDirectoryName(targetpath);
                         if (!options.Dryrun && !m_systemIO.DirectoryExists(folderpath))
                         {
                             result.AddWarning(string.Format("Creating missing folder {0} for  file {1}", folderpath, targetpath), null);
                             m_systemIO.DirectoryCreate(folderpath);
                         }
                         
                         // TODO: Much faster if we iterate the volume and checks what blocks are used,
                         // because the compressors usually like sequential reading
                         using(var file = m_systemIO.FileOpenReadWrite(targetpath))
                             foreach(var targetblock in restorelist.Blocks)
                             {
                                 file.Position = targetblock.Offset;
                                 var size = blocks.ReadBlock(targetblock.Key, blockbuffer);
                                 if (targetblock.Size == size)
                                 {
                                     file.Write(blockbuffer, 0, size);
                                     blockmarker.SetBlockRestored(restorelist.FileID, targetblock.Offset / blocksize, targetblock.Key, size);
                                 }   
                                 
                             }
                         
                         if (updateCounter++ % 20 == 0)
                             blockmarker.UpdateProcessed(result.OperationProgressUpdater);
                     }
                     catch (Exception ex)
                     {
                         result.AddWarning(string.Format("Failed to patch file: \"{0}\", message: {1}, message: {1}", targetpath, ex.Message), ex);
                     }
 	                
                     try
                     {
                         ApplyMetadata(targetpath, database);
                     }
                     catch (Exception ex)
                     {
                         result.AddWarning(string.Format("Failed to apply metadata to file: \"{0}\", message: {1}", targetpath, ex.Message), ex);
                     }
                 }
             }
             
             blockmarker.UpdateProcessed(result.OperationProgressUpdater);
             blockmarker.Commit(result);
         }
     }