Example #1
0
        /// <summary>
        /// Get directory contents.
        /// </summary>
        /// <param name="subpath"></param>
        /// <returns>Directory contents</returns>
        public IDirectoryContents GetDirectoryContents(string subpath)
        {
            // Assert enabled feature
            if (!options.CanBrowse)
            {
                throw new NotSupportedException(nameof(GetDirectoryContents));
            }
            try
            {
                // Read entry.
                IEntry entry = FileSystem.GetEntry(subpath, token);
                // Directory doesn't exist
                if (entry == null || !entry.IsDirectory())
                {
                    return(NotFoundDirectoryContents.Singleton);
                }
            }
            catch (NotSupportedException) { /*GetEntry is not supported, try Browse() next*/ }
            // Browse
            IDirectoryContent entries = FileSystem.Browse(subpath, token);

            //
            if (!entries.Exists)
            {
                return(NotFoundDirectoryContents.Singleton);
            }
            // Create infos
            IFileInfo[] infos = new IFileInfo[entries.Count];
            for (int i = 0; i < entries.Count; i++)
            {
                infos[i] = new FileInfo(FileSystem, entries[i], options, token);
            }
            // Wrap
            return(new DirectoryContents(infos));
        }
 /// <summary>
 /// If <see cref="IDirectoryContent.Exists"/> is false then throws <see cref="DirectoryNotFoundException"/>.
 /// </summary>
 /// <param name="browseResult"></param>
 /// <returns><paramref name="browseResult"/></returns>
 /// <exception cref="DirectoryNotFoundException">If <paramref name="browseResult"/> referes to non-existing path.</exception>
 public static IDirectoryContent AssertExists(this IDirectoryContent browseResult)
 {
     if (!browseResult.Exists)
     {
         throw new DirectoryNotFoundException(browseResult.Path);
     }
     return(browseResult);
 }
Example #3
0
 /// <summary>
 /// Browse a list of embedded resources.
 ///
 /// For example:
 ///     "assembly.res1"
 ///     "assembly.res2"
 /// </summary>
 /// <param name="path"></param>
 /// <param name="option">(optional) operation specific option; capability constraint, a session, security token or credential. Used for authenticating, authorizing or restricting the operation.</param>
 /// <returns></returns>
 public IDirectoryContent Browse(string path, IOption option = null)
 {
     if (path == null)
     {
         throw new ArgumentNullException(nameof(path));
     }
     if (IsDisposed)
     {
         throw new ObjectDisposedException(GetType().FullName);
     }
     if (path == "")
     {
         return(entries ?? (entries = CreateEntries()));
     }
     return(new DirectoryNotFound(this, path));
 }
        /// <summary>
        /// Vists tree structure of filesystem.
        ///
        /// Starts at <paramref name="path"/> if provided, otherwise starts at root "".
        /// <paramref name="depth"/> sets maximum visit depths.
        ///
        /// ""
        /// ├──""
        /// │  ├──"mnt"
        /// │  ├──"tmp"
        /// │  │  └──"helloworld.txt"
        /// │  └──"usr"
        /// │     └──"lex"
        /// └──"c:"
        ///    └──"dir"
        ///       └──"dir"
        ///
        ///
        /// Any thrown exceptions are printed into the line that produced the error.
        /// </summary>
        /// <param name="filesystem"></param>
        /// <param name="path"></param>
        /// <param name="depth">maximum visit depth</param>
        /// <param name="option">(optional) operation specific option; capability constraint, a session, security token or credential. Used for authenticating, authorizing or restricting the operation.</param>
        /// <exception cref="Exception">any exception that GetEntry or Browse can throw</exception>
        /// <exception cref="IOException">If Browse returns an entry whose path is not under parent entry's path</exception>
        public static IEnumerable <Line> VisitTree(this IFileSystem filesystem, string path = "", int depth = Int32.MaxValue, IOption option = null)
        {
            List <Line> queue = new List <Line>();
            IEntry      entry = filesystem.GetEntry(path, option);

            if (entry == null)
            {
                yield break;
            }
            queue.Add(new Line(entry, 0, 0UL));
            while (queue.Count > 0)
            {
                // Next entry
                int  lastIx = queue.Count - 1;
                Line line   = queue[lastIx];
                queue.RemoveAt(lastIx);

                // Children
                if (line.Entry.IsDirectory() && line.Level < depth)
                {
                    int startIndex = queue.Count;
                    try
                    {
                        // Browse
                        IDirectoryContent content = filesystem.Browse(line.Entry.Path, option);
                        // Assert children don't refer to the parent of the parent
                        foreach (IEntry child in content)
                        {
                            if (line.Entry.Path.StartsWith(child.Path))
                            {
                                throw new IOException($"{child.Path} cannot be child of {line.Entry.Path}");
                            }
                        }
                        // Bitmask when this level continues
                        ulong levelContinuesBitMask = line.LevelContinuesBitMask | (line.Level < 64 ? 1UL << line.Level : 0UL);
                        // Add children in reverse order
                        foreach (IEntry child in content)
                        {
                            queue.Add(new Line(child, line.Level + 1, levelContinuesBitMask));
                        }
                        // Sort the entries that were added
                        if (content.Count > 1)
                        {
                            sorter.QuickSortInverse(ref queue, startIndex, queue.Count - 1);
                        }
                        // Last entry doesn't continue on its level.
                        if (content.Count >= 1)
                        {
                            queue[startIndex] = queue[startIndex].NewLevelContinuesBitMask(line.LevelContinuesBitMask);
                        }
                    }
                    catch (Exception e)
                    {
                        // Add error to be yielded along
                        line.Error = e;
                    }
                }

                // yield line
                yield return(line);
            }
        }
Example #5
0
        /// <summary>Estimate viability of operation.</summary>
        /// <exception cref="FileNotFoundException">If <see cref="SrcPath"/> is not found.</exception>
        /// <exception cref="FileSystemExceptionFileExists">If <see cref="Path"/> already exists.</exception>
        protected override void InnerEstimate()
        {
            PathConverter pathConverter = new PathConverter(SrcPath, Path);
            List <IEntry> queue         = new List <IEntry>();

            // Src
            IEntry e = SrcFileSystem.GetEntry(SrcPath, srcOption.OptionIntersection(session.Option));

            // Src not found
            if (e == null)
            {
                // Throw
                if (EffectivePolicy.HasFlag(OperationPolicy.SrcThrow))
                {
                    throw new FileNotFoundException(SrcPath);
                }
                // Skip
                if (EffectivePolicy.HasFlag(OperationPolicy.SrcSkip))
                {
                    SetState(OperationState.Skipped); return;
                }
                // Fail anyway
                throw new FileNotFoundException(SrcPath);
            }

            queue.Add(e);
            while (queue.Count > 0)
            {
                try
                {
                    // Next entry
                    int    lastIx = queue.Count - 1;
                    IEntry entry  = queue[lastIx];
                    queue.RemoveAt(lastIx);

                    // Omit package mounts
                    if (session.Policy.HasFlag(OperationPolicy.OmitMountedPackages) && entry.IsPackageMount())
                    {
                        continue;
                    }

                    // Process directory
                    if (entry.IsDirectory())
                    {
                        // Browse children
                        IDirectoryContent content = SrcFileSystem.Browse(entry.Path, srcOption.OptionIntersection(session.Option));
                        // Assert children don't refer to the parent of the parent
                        foreach (IEntry child in content)
                        {
                            if (entry.Path.StartsWith(child.Path))
                            {
                                throw new IOException($"{child.Path} cannot be child of {entry.Path}");
                            }
                        }
                        // Visit child
                        for (int i = content.Count - 1; i >= 0; i--)
                        {
                            queue.Add(content[i]);
                        }
                        // Convert path
                        string _dstPath;
                        if (!pathConverter.ParentToChild(entry.Path, out _dstPath))
                        {
                            throw new Exception("Failed to convert path");
                        }
                        // Add op
                        if (_dstPath != "")
                        {
                            Ops.Add(new CreateDirectory(session, FileSystem, _dstPath, Option.OptionIntersection(session.Option), OpPolicy));
                        }
                    }

                    // Process file
                    else if (entry.IsFile())
                    {
                        // Convert path
                        string _dstPath;
                        if (!pathConverter.ParentToChild(entry.Path, out _dstPath))
                        {
                            throw new Exception("Failed to convert path");
                        }
                        // Add op
                        Ops.Add(new CopyFile(session, SrcFileSystem, entry.Path, FileSystem, _dstPath, srcOption.OptionIntersection(session.Option), Option.OptionIntersection(session.Option), OpPolicy));
                    }
                }
                catch (Exception error) when(SetError(error))
                {
                }
            }

            base.InnerEstimate();
        }
        /// <summary>Estimate viability of operation.</summary>
        /// <exception cref="FileNotFoundException">If <see cref="Path"/> is not found.</exception>
        /// <exception cref="FileSystemExceptionFileExists">If <see cref="Path"/> already exists.</exception>
        protected override void InnerEstimate()
        {
            List <Delete> dirDeletes = new List <Delete>();

            try
            {
                List <IEntry> queue = new List <IEntry>();
                IEntry        e     = FileSystem.GetEntry(Path, Option.OptionIntersection(session.Option));
                if (e == null)
                {
                    throw new FileNotFoundException(Path);
                }
                queue.Add(e);
                while (queue.Count > 0)
                {
                    try
                    {
                        // Next entry
                        int    lastIx = queue.Count - 1;
                        IEntry entry  = queue[lastIx];
                        queue.RemoveAt(lastIx);

                        // Omit package mounts
                        if (session.Policy.HasFlag(OperationPolicy.OmitMountedPackages) && entry.IsPackageMount())
                        {
                            continue;
                        }

                        // Process directory
                        if (entry.IsDirectory())
                        {
                            // Browse children
                            IDirectoryContent content = FileSystem.Browse(entry.Path, Option.OptionIntersection(session.Option));
                            // Assert children don't refer to the parent of the parent
                            foreach (IEntry child in content)
                            {
                                if (entry.Path.StartsWith(child.Path))
                                {
                                    throw new IOException($"{child.Path} cannot be child of {entry.Path}");
                                }
                            }
                            // Visit children
                            for (int i = content.Count - 1; i >= 0; i--)
                            {
                                queue.Add(content[i]);
                            }
                            // Add op
                            dirDeletes.Add(new Delete(session, FileSystem, entry.Path, false));
                        }

                        // Process file
                        else if (entry.IsFile())
                        {
                            // Add op
                            Ops.Add(new Delete(session, FileSystem, entry.Path, false, Option.OptionIntersection(session.Option), OpPolicy));
                        }
                    }
                    catch (Exception error) when(SetError(error))
                    {
                    }
                }
            }
            finally
            {
                // Add directory deletes
                for (int i = dirDeletes.Count - 1; i >= 0; i--)
                {
                    Ops.Add(dirDeletes[i]);
                }
            }

            // Estimate added ops
            base.InnerEstimate();
        }
Example #7
0
        public static void Main(string[] args)
        {
            {
                #region Snippet_1a
                IFileSystem fs = new FileSystem(@"C:\Temp\");
                #endregion Snippet_1a
            }
            {
                #region Snippet_1b
                IFileSystem fs = new FileSystem("");
                #endregion Snippet_1b
            }

            {
                IFileSystem fs = new FileSystem("");
                #region Snippet_2a
                IDirectoryContent contents = fs.Browse("C:/Windows/");
                #endregion Snippet_2a

                #region Snippet_2d
                foreach (IEntry entry in fs.Browse("C:/Windows/"))
                {
                    Console.WriteLine(entry.Path);
                }
                #endregion Snippet_2d

                #region Snippet_2e
                foreach (var entry in fs.Browse("C:/Windows/").AssertExists())
                {
                    Console.WriteLine(entry.Path);
                }
                #endregion Snippet_2e

                {
                    #region Snippet_2f
                    IEntry e = FileSystem.OS.GetEntry("C:/Windows/win.ini");
                    Console.WriteLine(e.Path);
                    #endregion Snippet_2f
                }
                {
                    #region Snippet_2g
                    IEntry e = FileSystem.OS.GetEntry("C:/Windows/win.ini").AssertExists();
                    #endregion Snippet_2g
                }

                #region Snippet_3a
                using (Stream s = fs.Open("file.txt", FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    Console.WriteLine(s.Length);
                }
                #endregion Snippet_3a

                #region Snippet_3b
                using (Stream s = fs.Open("somefile.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
                {
                    s.WriteByte(32);
                }
                #endregion Snippet_3b

                #region Snippet_5
                fs.CreateDirectory("dir/");
                #endregion Snippet_5

                #region Snippet_6
                fs.Delete("dir/", recurse: true);
                #endregion Snippet_6

                #region Snippet_7
                fs.CreateDirectory("dir/");
                fs.Move("dir/", "new-name/");
                #endregion Snippet_7
                fs.Delete("new-name/");
            }
            {
                IFileSystem fs = FileSystem.Temp;
                if (fs.Exists("myfile"))
                {
                    fs.SetFileAttribute("myfile", FileAttributes.Normal);
                    fs.Delete("myfile");
                }

                fs.CreateFile("myfile", new byte[] { 1 });
                #region Snippet_7f
                fs.SetFileAttribute("myfile", FileAttributes.ReadOnly);
                #endregion Snippet_7f
                fs.SetFileAttribute("myfile", FileAttributes.Normal);
                fs.Delete("myfile");
            }

            {
                #region Snippet_7x1
                FileSystem.OS.GetEntry("C:/Windows/win.ini");
                #endregion Snippet_7x1
            }


            {
                #region Snippet_8a
                IFileSystem fs = FileSystem.OS;
                #endregion Snippet_8a
            }

            {
                #region Snippet_8b
                foreach (var line in FileSystem.OS.VisitTree(depth: 2))
                {
                    Console.WriteLine(line);
                }
                #endregion Snippet_8b
            }
            {
                #region Snippet_8b2
                FileSystem.OS.PrintTo(Console.Out, depth: 2, format: PrintTree.Format.DefaultPath);
                #endregion Snippet_8b2
            }
            {
                #region Snippet_8c
                FileSystem.OS.PrintTo(Console.Out, depth: 3, format: PrintTree.Format.DefaultPath);
                #endregion Snippet_8c
            }

            {
                #region Snippet_8d
                FileSystem.Application.PrintTo(Console.Out);
                #endregion Snippet_8d
            }

            {
                #region Snippet_8e
                FileSystem.Temp.PrintTo(Console.Out, depth: 1);
                #endregion Snippet_8e
            }

            {
                // <Snippet_8f>
                foreach (var line in FileSystem.Temp.VisitTree(depth:2))
                {
                    Console.WriteLine(line.Entry.PhysicalPath());
                }
                // </Snippet_8f>
            }
            {
                // <Snippet_8g>
                FileSystem.Temp.PrintTo(
                    output: Console.Out,
                    depth: 2,
                    format: PrintTree.Format.Default | PrintTree.Format.PhysicalPath);
                // </Snippet_8g>
            }

            {
                // <Snippet_9a>
                IObserver <IEvent>  observer = new Observer();
                IFileSystemObserver handle   = FileSystem.OS.Observe("C:/**", observer);
                // </Snippet_9a>
            }
            {
                // <Snippet_9b>
                using (var handle = FileSystem.Temp.Observe("*.dat", new PrintObserver()))
                {
                    FileSystem.Temp.CreateFile("file.dat", new byte[] { 32, 32, 32, 32 });
                    FileSystem.Temp.Delete("file.dat");

                    Thread.Sleep(1000);
                }
                // </Snippet_9b>
            }

            {
                // <Snippet_9c>
                IObserver <IEvent> observer = new Observer();
                FileSystem.OS.Observe("C:/**", observer, eventDispatcher: EventDispatcher.Instance);
                // </Snippet_9c>
            }

            {
                // <Snippet_9d>
                IObserver <IEvent> observer = new Observer();
                FileSystem.OS.Observe("C:/**", observer, eventDispatcher: EventTaskDispatcher.Instance);
                // </Snippet_9d>
            }

            {
                #region Snippet_10a
                // Init
                object obj = new ReaderWriterLockSlim();
                IFileSystemDisposable fs = new FileSystem("").AddDisposable(obj);

                // ... do work ...

                // Dispose both
                fs.Dispose();
                #endregion Snippet_10a
            }
            {
                #region Snippet_10b
                IFileSystemDisposable fs = new FileSystem("")
                                           .AddDisposeAction(f => Console.WriteLine("Disposed"));
                #endregion Snippet_10b
            }
            {
                #region Snippet_10c
                FileSystem fs = new FileSystem("");
                fs.Browse("");

                // Postpone dispose
                IDisposable belateDisposeHandle = fs.BelateDispose();
                // Start concurrent work
                Task.Run(() =>
                {
                    // Do work
                    Thread.Sleep(1000);
                    fs.GetEntry("");
                    // Release belate handle. Disposes here or below, depending which thread runs last.
                    belateDisposeHandle.Dispose();
                });

                // Start dispose, but postpone it until belatehandle is disposed in another thread.
                fs.Dispose();
                #endregion Snippet_10c
            }
        }