/// <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);
            }
        }
Exemple #2
0
        /// <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);
            }
        }