/// <summary> /// Moves the file. /// </summary> public void MoveFile([NotNull] string sourceFileName, [NotNull] string destFileName, [CanBeNull] IFileSystem destinationSystem = null) { Validate.ArgumentNotNull(sourceFileName, "sourceFileName"); Validate.ArgumentNotNull(destFileName, "destFileName"); if (destinationSystem == null || destinationSystem == this) { File.Move(sourceFileName, destFileName); } else { var operations = new VirtualFileOperations(this, destinationSystem); operations.MoveFile(sourceFileName, destFileName); } }
/// <summary> /// Moves or renames the file. /// </summary> /// <param name="sourceFileName">Name of the source file.</param> /// <param name="destFileName">New name and path of moved file.</param> /// <param name="destinationSystem">The destination system. Optional.</param> /// <exception cref="FileNotFoundException">Cannot find source file to move.</exception> /// <exception cref="DirectoryNotFoundException">Cannot find destination directory for move operation.</exception> /// <exception cref="IOException">Destination file already exists.</exception> public void MoveFile([NotNull] string sourceFileName, [NotNull] string destFileName, [CanBeNull] IFileSystem destinationSystem = null) { Validate.ArgumentNotNull(sourceFileName, "sourceFileName"); Validate.ArgumentNotNull(destFileName, "destFileName"); CheckDisposed(); // destination and source must be file names. directory names are not supported (same as native io). bool sameSystem = destinationSystem == null || destinationSystem == this; // move inside same volume if (sameSystem && sourceFileName == destFileName) { return; } if (sameSystem) { var sourceVfn = new VirtualFileName(sourceFileName); var destVfn = new VirtualFileName(destFileName); NodeLocker srcResult; NodeLocker destResult; if (string.Equals(sourceVfn.Path, destVfn.Path, StringComparison.InvariantCultureIgnoreCase)) { // same folder, rename file. srcResult = destResult = FindNode(sourceVfn, true, true); } else if (sourceVfn.AllSegments.Count() > destVfn.AllSegments.Count()) { // lock longer path first srcResult = FindNode(sourceVfn, true, true); destResult = FindNode(destVfn, true, true); } else { destResult = FindNode(destVfn, true, true); srcResult = FindNode(sourceVfn, true, true); } using (srcResult) { var sourceDir = srcResult.Directory; if (sourceDir == null) { throw new FileNotFoundException("Cannot find source file to move.", sourceFileName); } using (destResult) { var destDir = destResult.Directory; if (destDir == null) { throw new DirectoryNotFoundException("Cannot find destination directory for move operation."); } if (destDir.FindChildEntry(destVfn.Name) != null) { throw new IOException("Destination file already exists."); } var sourceFile = sourceDir.FindChildEntry(sourceVfn.Name); if (sourceFile == null || sourceFile is DirectoryNode) { throw new FileNotFoundException("Cannot find source file to move.", sourceFileName); } using (NodeLocker.Lock(sourceFile, true)) { sourceDir.FindAndRemoveChildEntry(sourceVfn.Name, false); destDir.AddChildEntry(destVfn.Name, false, sourceFile.Address); } } } } else { var operations = new VirtualFileOperations(this, destinationSystem); operations.MoveFile(sourceFileName, destFileName); } }