/// <summary> Renames the specified sub-directory and returns the directory entry. </summary>
        /// <exception cref="FileNotFoundException"> Thrown when the requested directory is not present. </exception>
        /// <param name="directoryName"> Name of the directory to rename. </param>
        /// <param name="newName"> The new directory name. </param>
        /// <returns> The VirtualDirectoryNode instance that was renamed. </returns>
        public VirtualDirectoryNode RenameDirectory(string directoryName, string newName)
        {
            _CheckDisposed();

            var dir = _SubDirectories.Value(VirtualFileInfo.CreateKey(directoryName));

            if (dir == null)
            {
                throw new DirectoryNotFoundException($"Directory '{directoryName}' does not exist in directory '{FullName}'.");
            }

            if (FileOrDirectoryExists(newName, out var newKey))
            {
                throw new InvalidOperationException($"A file or directory already exists in '{FullName}' with the name '{newName}'.");
            }
            else
            {
                _SubDirectories.Remove(dir.Key);
                dir._Name = newName;
                dir._Key  = newKey;
                _SubDirectories[newKey] = dir;

                return(dir);
            }
        }
 internal virtual void _Directory_FileChanged(VirtualDirectoryNode origin, VirtualFileInfo file)
 {
     if (OnChanged(file.FullName))
     {
         Target.FileChanged.Event -= _Directory_FileChanged;
     }
 }
        // --------------------------------------------------------------------------------------------------------------------

        /// <summary> Creates a virtual file in this directory with the given filename. </summary>
        /// <exception cref="InvalidOperationException"> Thrown if the name is invalid or already exists. </exception>
        /// <param name="name"> The name for the new file. </param>
        /// <returns> The new file. </returns>
        public VirtualFileInfo CreateFile(string name)
        {
            _CheckDisposed();

            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException(PathUtils.NOT_NULL_EMPTY_OR_WHITESPACE_MSG, nameof(name));
            }

            if (PathUtils.HasInvalidFilenameChars(name))
            {
                throw new InvalidOperationException($"Filename '{name}' is not valid.");
            }

            if (FileOrDirectoryExists(name, out var key))
            {
                throw new InvalidOperationException($"A file or directory already exists with the name '{name}'.");
            }

            var file = new VirtualFileInfo(this, name);

            _Files[key]          = file;
            file.Changed.Event  += _OnFileChanged;
            file.Disposed.Event += _OnFileDisposed;

            FileAdded.Raise(file);

            return(file);
        }
        // --------------------------------------------------------------------------------------------------------------------

        /// <summary> Renames the specified file and returns the file entry. </summary>
        /// <exception cref="FileNotFoundException"> Thrown when the requested file is not present. </exception>
        /// <param name="filename"> Filename of the file. </param>
        /// <param name="newName"> The new filename. </param>
        /// <returns> The VirtualFileInfo instance that was renamed. </returns>
        public VirtualFileInfo RenameFile(string filename, string newName)
        {
            _CheckDisposed();

            var file = _Files.Value(VirtualFileInfo.CreateKey(filename));

            if (file == null)
            {
                throw new FileNotFoundException($"The file was not found in directory '{FullName}'.", filename);
            }

            if (FileOrDirectoryExists(newName, out var newKey))
            {
                throw new InvalidOperationException($"A file or directory already exists in '{FullName}' with the name '{newName}'.");
            }
            else
            {
                _Files.Remove(file.Key);
                file._Name     = newName;
                file._Key      = newKey;
                _Files[newKey] = file;

                return(file);
            }
        }
        private void _OnFileDisposed(VirtualFileInfo origin, VirtualFileInfo file)
        {
            if (file._Directory == this)
            {
                _Files.Remove(file.Key);
                file.Changed.Event  -= _OnFileChanged;
                file.Disposed.Event -= _OnFileDisposed;
            }

            FileDeleted.Raise(file);
            _Parent?._OnFileDisposed(file, file);
        }
        /// <summary> Deletes a file by name and returns the deleted file. </summary>
        /// <param name="name"> The name of a file to delete. </param>
        /// <returns> The deleted VirtualFileInfo, or null if not found. </returns>
        public VirtualFileInfo DeleteFile(string name)
        {
            _CheckDisposed();

            var file = _Files.Value(VirtualFileInfo.CreateKey(name));

            if (file != null)
            {
                file.Delete();
                return(file);
            }
            else
            {
                return(null); // (not found)
            }
        }
        // --------------------------------------------------------------------------------------------------------------------

        /// <summary> Gets a directory relative to the current directory using a slash-delimited path ('/' or '\' will work). </summary>
        /// <exception cref="InvalidOperationException"> Thrown when the requested operation is invalid. </exception>
        /// <param name="path"> Full path of the file directory. </param>
        /// <param name="createIfNotExists">
        ///     (Optional) True to create any missing directory entries. If false, null is returned if the directory was not found.
        /// </param>
        /// <returns> The directory if found, or null otherwise. </returns>
        public VirtualDirectoryNode GetDirectory(string path, bool createIfNotExists)
        {
            _CheckDisposed();

            if ((path[0] == '\\' || path[0] == '/') && this != Root)
            {
                return(Root.GetDirectory(path, createIfNotExists)); // (request search at the root level; send upwards)
            }
            var names = path?.Trim().Split('/', '\\') ?? new string[0];
            VirtualDirectoryNode dir = this, nextDir = null;

            for (var i = 0; i < names.Length; ++i)
            {
                var name = names[i].Trim();

                if (!string.IsNullOrWhiteSpace(name))
                {
                    var entryKey = VirtualFileInfo.CreateKey(name);
                    nextDir = dir._SubDirectories.Value(entryKey);

                    if (nextDir == null)
                    {
                        if (createIfNotExists)
                        {
                            if (_Files.ContainsKey(entryKey))
                            {
                                throw new InvalidOperationException($"Cannot create directory '{path}' - a directory already exists by the name '{name}' in '{dir.FullName}'.");
                            }

                            nextDir = new VirtualDirectoryNode(this, name)
                            {
                                _Key = entryKey
                            };
                            _SubDirectories[entryKey] = nextDir;
                        }
                        else
                        {
                            return(null); // (not found)
                        }
                    }
                    dir = nextDir;
                }
            }
            return(dir);
        }
        /// <summary>
        ///     Gets a file using the specific filename.  If the filename contains a path then it will be used to locate the
        ///     directory relative to the current directory.
        /// </summary>
        /// <exception cref="InvalidOperationException"> Thrown when the requested operation is invalid. </exception>
        /// <param name="filePath"> Full path of the file directory. </param>
        /// <param name="createIfNotExists">
        ///     (Optional) True to create new directory and file entries if missing. If false, null is returned if the directory or
        ///     file was not found.
        /// </param>
        /// <returns> The directory if found, or null otherwise. </returns>
        public VirtualFileInfo GetFile(string filePath, bool createIfNotExists)
        {
            if (string.IsNullOrWhiteSpace(filePath))
            {
                return(null);                                     // (nothing given)
            }
            filePath = filePath.Trim();
            var filename = Path.GetFileName(filePath);

            if (string.IsNullOrWhiteSpace(filename))
            {
                return(null);                                     // (no filename given)
            }
            var dirPath = Path.GetDirectoryName(filePath);
            var dir     = GetDirectory(dirPath, createIfNotExists);

            if (dir == null)
            {
                return(null);
            }

            var entryKey = VirtualFileInfo.CreateKey(filename);
            var file     = dir._Files.Value(entryKey);

            if (file == null && createIfNotExists)
            {
                if (_SubDirectories.ContainsKey(entryKey))
                {
                    throw new InvalidOperationException($"Cannot create file '{filePath}' - a directory already exists by that name.");
                }
                file = new VirtualFileInfo(dir, filename)
                {
                    _Key = entryKey
                };
                _Files[entryKey] = file;
            }

            return(file);
        }
Exemple #9
0
 public VirtualFileData(VirtualFileInfo virtualFileInfo)
 {
     VirtualFileInfo = virtualFileInfo;
 }
 /// <summary> Deletes a sub-directory by name and returns the deleted directory. </summary>
 /// <param name="name"> The name of a sub-directory to delete. </param>
 /// <returns> The deleted VirtualDirectoryNode, or null if not found. </returns>
 public VirtualDirectoryNode DeleteDirectory(string name)
 {
     _CheckDisposed();
     return(DeleteDirectory(_SubDirectories.Value(VirtualFileInfo.CreateKey(name))));
 }
 private void _OnFileChanged(VirtualFileInfo origin, VirtualFileInfo file)
 {
     FileChanged.Raise(file);
     _Parent?._OnFileChanged(file, file);
 }
        // --------------------------------------------------------------------------------------------------------------------

        /// <summary> Queries if a given file or directory exists. </summary>
        /// <param name="name"> The name for this directory entry. </param>
        /// <returns> True if it exists, false otherwise. </returns>
        public bool FileOrDirectoryExists(string name, out string entryKey)
        {
            _CheckDisposed();
            entryKey = VirtualFileInfo.CreateKey(name);
            return(_SubDirectories.ContainsKey(entryKey) || _Files.ContainsKey(entryKey));
        }