private MultiThreadedCopierCopyFileResults PerformFileCopy() { if (Status == CopierStatus.Busy) { throw new ApplicationException("Copy can't be called again before it completes."); } Status = CopierStatus.Busy; const string separator = "-|-"; var inputExceptions = EnsureOperationInputArguments(); if (inputExceptions.Any()) { throw new ApplicationException(string.Join(separator, (from index in Enumerable.Range(0, inputExceptions.Count) select string.Format("Error: {0}, Message: '{1}'{2}", index, inputExceptions[index], separator)))); } var results = new MultiThreadedCopierCopyFileResults { Success = false, Message = "Operation was not performed." }; if (File.Exists(DestinationPath)) { var fileBackUpPath = BackUpFile(DestinationPath); RaiseFileCopyUpdateMessage("Desitnation file preserved: " + fileBackUpPath); File.Delete(DestinationPath); RaiseFileCopyUpdateMessage("Destination file deleted: " + DestinationPath); } var fileInfo = new FileInfo(SourcePath); var totalSize = fileInfo.Length; //var chunkSize = Convert.ToInt64(totalSize*.10); var chunkSize = (long) (1024000 * 7); ReadTaskCounter = totalSize / chunkSize; if (chunkSize*ReadTaskCounter < totalSize) ReadTaskCounter++; var finalItemChunkSize = Convert.ToInt32(totalSize - ((ReadTaskCounter - 1) * chunkSize)); var buffer = new byte[chunkSize]; ReadFileTaskList.Clear(); RaiseFileCopyUpdateMessage("Total File Size to copy: {0}", totalSize); RaiseFileCopyUpdateMessage("Total number of chunks: {0}", ReadTaskCounter); RaiseFileCopyUpdateMessage("Size of last chunk: {0}", finalItemChunkSize); RaiseFileCopyUpdateMessage("Chunk Size: {0}", chunkSize); if (File.Exists(DestinationPath)) { Path.GetFileNameWithoutExtension(DestinationPath); } var lastIndex = 0; for (var i = 0; i < ReadTaskCounter; i++) { var isLastRead = i == ReadTaskCounter - 1; var currentChunkSize = isLastRead ? finalItemChunkSize : Convert.ToInt32(chunkSize); var fileStream = new FileStream(SourcePath, FileMode.Open, FileAccess.Read, FileShare.Read); var offset = chunkSize * i; fileStream.Seek(offset, SeekOrigin.Begin); var taskInfo = new ReadTaskInfo<int>() { DispatchOrder = Convert.ToUInt16(i), ReadResultsBuffer = buffer, FileStream = fileStream, AttemptedReadSize = currentChunkSize, IsLastRead = isLastRead, PositionOffset = offset }; lock (ReadFileTaskList) { ReadFileTaskList.Add(taskInfo); } taskInfo.Task = fileStream.ReadAsync(buffer, 0, currentChunkSize); taskInfo.Task.ContinueWith(OnFileChunkRead); RaiseFileCopyUpdateMessage("Dispatch Read Item # {0}", i + 1); } results.Success = true; results.Message = string.Empty; return results; }
private void OnFileChunkWrite(Task task) { WriteTaskCounter++; WriteTaskInfo taskInfo; lock (WriteFileTaskList) { taskInfo = WriteFileTaskList.First(ti => ti.Task == task); } bool lastWriteTaskIsCompleted = WriteTaskCounter == ReadTaskCounter; if (taskInfo.FileStream != null) { taskInfo.FileStream.Close(); taskInfo.FileStream.Dispose(); taskInfo.FileStream = null; taskInfo.ReadTaskInfo.ReadResultsBuffer = null; } RaiseFileCopyUpdateMessage("Write Task item {0} of {1} completed.", taskInfo.DispatchOrder + 1, ReadTaskCounter); if (lastWriteTaskIsCompleted) { Status = CopierStatus.Idle; if (FileCopied != null) { FileCopied(this, EventArgs.Empty); } } }