Пример #1
0
        /// <summary>
        /// Copies the file.
        /// </summary>
        /// <param name="sourceFileName">Name of the source file.</param>
        /// <param name="destFileName">Name of the destination file.</param>
        /// <param name="destinationSystem">The destination system. Optional.</param>
        /// <exception cref="FileNotFoundException">Cannot find source file to copy.</exception>
        /// <exception cref="DirectoryNotFoundException">Specified destination path does not exist.</exception>
        public void CopyFile([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);
                using (var srcResult = FindNode(sourceVfn, false)) // lock file for reading, we're copying
                {
                    var sourceFile = srcResult.File;
                    if (sourceFile == null)
                    {
                        throw new FileNotFoundException("Cannot find source file to copy.", sourceFileName);
                    }

                    var vfn = new VirtualFileName(destFileName);

                    // lock destination dir for writing - new file will be created there.
                    using (var destResult = FindNode(vfn, true, true))
                    {
                        var parentDir = destResult.Directory;
                        if (parentDir == null)
                        {
                            throw new DirectoryNotFoundException("Specified destination path does not exist.");
                        }

                        var destFile = _record.CreateFileNode(vfn.Name, parentDir);
                        using (NodeLocker.Lock(destFile, true))
                        {
                            CopyNodeData(sourceFile, destFile);
                        }
                    }
                }
            }
            else
            {
                var operations = new VirtualFileOperations(this, destinationSystem);
                operations.CopyFile(sourceFileName, destFileName);
            }
        }
Пример #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);
            }
        }
Пример #3
0
        public IFile OpenFile([NotNull] string fileName, bool canWrite)
        {
            Validate.ArgumentNotNull(fileName, "fileName");

            CheckDisposed();

            var vfn = new VirtualFileName(fileName);

            VirtualFile ret;
            // no using clause, since file must remain locked.
            var result = FindNode(vfn, false, canWrite);
            try
            {
                var currentNode = result.File;
                if (currentNode == null)
                {
                    throw new FileNotFoundException("File not found.", fileName);
                }

                ret = new VirtualFile(currentNode, canWrite);
            }
            catch
            {
                result.Dispose();
                throw;
            }

            return ret;
        }
Пример #4
0
 /// <summary>
 /// Gets the information about file or directory at specified path.
 /// Does not fail if specified path does not exists.
 /// </summary>
 public Info GetFileInfo([NotNull] string path)
 {
     CheckDisposed();
     var vfn = new VirtualFileName(path);
     using (var result = FindNode(vfn, false))
     {
         return new Info
         {
             Exists = result.Exists,
             FileSize = result.File == null ? 0 : result.File.FileSize,
             IsDirectory = result.Directory != null,
             CreatedDate = result.Node == null ? DateTime.MinValue : result.Node.CreatedDate,
             ModifiedDate = result.Node == null ? DateTime.MinValue : result.Node.ModifiedDate
         };
     }
 }
Пример #5
0
        public NodeStorage MountDisk(string fileName)
        {
            var vfn = new VirtualFileName(fileName);
            var locker = FindNode(vfn, false, true);
            try
            {
                var file = locker.File;
                if (file == null)
                    return null;

                return new NodeStorage(file);
            }
            finally
            {
                locker.Dispose();
            }
        }
Пример #6
0
        public IEnumerable<string> FindFile([NotNull] string path, [NotNull] string pattern, bool recursive)
        {
            Validate.ArgumentNotNull(path, "path");
            Validate.ArgumentNotNull(pattern, "pattern");

            CheckDisposed();
            var vfn = new VirtualFileName(path);
            List<string> matches;
            List<string> dirsToSearch;
            using (var result = FindNode(vfn, false))
            {
                var parentDirectory = result.Directory;
                if (parentDirectory == null)
                {
                    // this situation is possible when directory is being changed,
                    // and target was removed. Don't fail, just skip.
                    yield break;
                }

                dirsToSearch = parentDirectory.GetAllChildDirectories().ToList();
                matches = parentDirectory.FindMatchingEntries(pattern).ToList();
            }

            // unlock directory here.
            foreach (var file in matches)
            {
                yield return VirtualFileName.Combine(vfn.FullName, file);
            }

            if (!recursive || !dirsToSearch.Any())
            {
                yield break;
            }

            foreach (var dir in dirsToSearch)
            {
                foreach (var fileName in FindFile(VirtualFileName.Combine(path, dir), pattern, true))
                {
                    yield return fileName;
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Deletes the file.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <exception cref="FileNotFoundException">File not found.</exception>
        public void DeleteFile([NotNull] string fileName)
        {
            Validate.ArgumentNotNull(fileName, "fileName");

            CheckDisposed();

            var vfn = new VirtualFileName(fileName);

            using (var result = FindNode(vfn, true, true))
            {
                var parentNode = result.Directory;
                if (parentNode == null)
                {
                    throw new FileNotFoundException("File not found.", fileName);
                }

                var fileNode = parentNode.FindAndRemoveChildEntry(vfn.Name, false);
                if (fileNode == null)
                {
                    throw new FileNotFoundException("File not found.", fileName);
                }

                _record.FreeNodeAndAllAllocatedBlocks(fileNode);
            }
        }
Пример #8
0
        /// <summary>
        /// Deletes the directory.
        /// </summary>
        /// <param name="path">The path to directory to delete.</param>
        /// <param name="recursive">If set to <c>true</c>, recursive directory removal is performed.</param>
        /// <exception cref="DirectoryNotFoundException">Specified path does not reference a directory.</exception>
        public void DeleteDirectory([NotNull] string path, bool recursive)
        {
            Validate.ArgumentNotNull(path, "path");

            CheckDisposed();

            // todo: recursive delete should not lock entire tree. parallel read should be possible.
            var vfn = new VirtualFileName(path);
            using (var result = FindNode(vfn, true, true))
            {
                var parentDirectory = result.Directory;
                if (parentDirectory == null)
                {
                    throw new DirectoryNotFoundException("Specified path does not reference a directory.");
                }

                var node = parentDirectory.FindAndRemoveChildEntry(vfn.Name, true);
                if (node == null)
                {
                    throw new DirectoryNotFoundException("Specified path does not reference a directory.");
                }

                DeallocateRecursive(node);
            }
        }
Пример #9
0
        public IFile CreateFile([NotNull] string fileName)
        {
            Validate.ArgumentNotNull(fileName, "fileName");

            CheckDisposed();

            var vfn = new VirtualFileName(fileName);

            VirtualFile ret;
            using (var result = FindNode(vfn, true, true))
            {
                var parentNode = result.Directory;
                if (parentNode == null)
                {
                    throw new DirectoryNotFoundException("Specified path does not reference a directory.");
                }

                var node = _record.CreateFileNode(vfn.Name, parentNode);
                node.LockWrite();
                ret = new VirtualFile(node, true);
            }
            return ret;
        }
Пример #10
0
        /// <summary>
        /// Creates the directory.
        /// </summary>
        /// <param name="path">The directory path to create.</param>
        /// <exception cref="DirectoryNotFoundException">Specified path does not reference a directory.</exception>
        public void CreateDirectory([NotNull] string path)
        {
            Validate.ArgumentNotNull(path, "path");

            CheckDisposed();

            var vfn = new VirtualFileName(path);
            using (var result = FindNode(vfn, true, true))
            {
                var parent = result.Directory;
                if (parent == null)
                {
                    throw new DirectoryNotFoundException("Specified path does not reference a directory.");
                }

                _record.CreateDirectoryNode(vfn.Name, parent);
            }
        }