public FileCopyReport(ReportType reportType, FileCopyOperation operation, int streamIndex, long chunkOffset, long chunkSize) { this._reportType = reportType; this._operation = operation; this._streamIndex = streamIndex; this._chunkOffset = chunkOffset; this._chunkSize = chunkSize; this._source = operation.Source; this._target = operation.Target; this._streamOffset = 0; this._streamSize = operation.BytesToTransfer; this.ContinuationType = reportType == ReportType.AbortedOperation ? ContinuationType.AbortOperation : ContinuationType.Proceed; }
private FileOperation NewFileCopyOperation() { var fileCopy = new FileCopyOperation( new DirectoryInfo(Source), new DirectoryInfo(Destination), GetFileFilters(), GetDirectoryFilters(), GetOptions()) { BufferSize = BufferSize, Credentials = GetCredentials(), WhatToCopy = GetWhatToCopy(), RetryCount = RetryCount, RetryInterval = TimeSpan.FromSeconds(RetryIntervalSeconds) }; return(ThreadCount.HasValue ? (FileOperation)fileCopy.MakeMultiThreaded(ThreadCount.Value ?? 8) : fileCopy); }
/// <summary> /// Copies a symbolic link if needed. /// </summary> /// <param name="source">The source.</param> /// <param name="target">The target.</param> /// <param name="callback">The callback.</param> /// <returns>The last report or <c>null</c>.</returns> private static IFileReport _CopySymbolicLinkIfNeeded(FileInfo source, FileInfo target, Action <IFileSystemReport> callback) { if (!source.IsSymbolicLink()) { return(null); } var operation = new FileCopyOperation(source, target, callback, false); operation.OperationStarted(); try { var targets = source.GetSymbolicLinkTarget(); target.CreateSymbolicLinkAt(targets); operation.CreatedLink(); return(operation.OperationFinished()); } catch (Exception e) { return(operation.OperationAborted(e)); } }
/// <summary> /// Copies the file asynchronous. /// This reads one chunk at a time and when the OS signals that a read is done, it starts writing that chunk while, possibly at the same time, reading the next. /// </summary> /// <param name="This">This source file.</param> /// <param name="target">The target file.</param> /// <param name="overwrite">if set to <c>true</c> overwrites existing; otherwise throws IOException.</param> /// <param name="allowHardLinks">if set to <c>true</c> allows creation of hard links.</param> /// <param name="dontResolveSymbolicLinks">if set to <c>true</c> [dont resolve symbolic links].</param> /// <param name="callback">The callback, if any.</param> /// <param name="allowedStreams">The allowed number of streams.</param> /// <param name="bufferSize">Size of the buffer.</param> /// <returns></returns> /// <exception cref="System.IO.FileNotFoundException">When source file does not exist</exception> /// <exception cref="System.IO.IOException">When target file exists and should not overwrite</exception> public static IFileReport CopyToAsync(this FileInfo This, FileInfo target, bool overwrite = false, bool allowHardLinks = false, bool dontResolveSymbolicLinks = false, Action <IFileSystemReport> callback = null, int allowedStreams = 1, int bufferSize = -1) { Contract.Requires(This != null); Contract.Requires(target != null); if (!File.Exists(This.FullName)) { throw new FileNotFoundException(string.Format(_EX_SOURCE_FILE_DOES_NOT_EXIST, This.FullName)); } // special hard link handling var sourceIsHardLink = This.IsHardLink(); if (sourceIsHardLink) { var targets = This.GetHardLinkTargets(); // if target file is already a hard link of the source, don't copy if (targets.Any(t => t.FullName == target.FullName)) { var operation = new FileCopyOperation(This, target, callback, false); operation.OperationStarted(); return(operation.OperationFinished()); } } if (File.Exists(target.FullName)) { if (!overwrite) { throw new IOException(string.Format(_EX_TARGET_FILE_ALREADY_EXISTS, target.FullName)); } File.Delete(target.FullName); } // create symlink at target with the same source if (dontResolveSymbolicLinks) { var copySymlink = _CopySymbolicLinkIfNeeded(This, target, callback); if (copySymlink != null) { return(copySymlink); } } var mainToken = new FileCopyOperation(This, target, callback, !This.IsOnSamePhysicalDrive(target), bufferSize); // create link if possible and allowed if (allowHardLinks && This.TryCreateHardLinkAt(target)) { // link creation successful mainToken.OperationStarted(); mainToken.CreatedLink(); return(mainToken.OperationFinished()); } // do copy var result = mainToken.OperationStarted(); // open streams try { mainToken.SourceStream = new FileStream(This.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, mainToken.ChunkSize, FileOptions.Asynchronous | FileOptions.SequentialScan); // set target size first to avoid fragmentation _SetFileSize(target, Math.Min(mainToken.TotalSize, _MAX_PREALLOCATION_SIZE)); mainToken.TargetStream = new FileStream(target.FullName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, mainToken.ChunkSize, FileOptions.Asynchronous | (mainToken.TotalSize < _MAX_CACHED_SIZE ? FileOptions.None : FileOptions.WriteThrough)); } catch (Exception e) { return(mainToken.OperationAborted(e)); } // trigger start reading if (mainToken.BytesToTransfer > 0) { mainToken.StartReading(); } else { result = mainToken.OperationFinished(); } return(result); }