• Lexical
Show / Hide Table of Contents
  • Lexical.FileSystem
    • Introduction
    • Abstractions
      • IFileSystem
        • IFileSystem
        • IFileSystemBrowse
        • IFileSystemCreateDirectory
        • IFileSystemDelete
        • IFileSystemFileAttribute
        • IFileSystemMount
        • IFileSystemMove
        • IFileSystemObserve
        • IFileSystemOpen
      • IEvent
      • IEntry
      • IOption
      • IToken
    • FileSystem
    • VirtualFileSystem
    • MemoryFileSystem
    • EmbeddedFileSystem
    • HttpFileSystem
    • Decoration
    • IFileProvider
    • Utility
      • DisposeList
      • FileScanner
      • VisitTree
      • File Operation
  • Lexical.FileProvider
    • Introduction
    • Package
    • Package.Abstractions
    • Root
    • Zip
    • Dll
    • SharpCompress
    • SharpZipLib
    • FileScanner
    • Utils
  • Lexical.Localization
    • Introduction
    • Tutorial
    • Asset
      • IAsset
      • IStringAsset
    • Line
      • ILine
      • ILineFactory
      • ILineRoot
      • ILineFormat
      • ILineLogger
      • LineComparer
    • File
      • ILineReader
      • ILineWriter
      • Ini
      • Json
      • Xml
      • Resx
      • Resources
    • Miscellaneous
      • Plurality
      • ICulturePolicy
      • IStringFormat
      • Dependency Injection
    • Practices
      • Class Library
      • Class Library DI
      • Class Library DI opt.
  • Lexical.Utilities
    • Introduction
    • UnicodeString
    • FileScanner
    • Permutation
    • Tuples
    • StructList

FileSystem

new FileSystem(path) creates an instance of filesystem at path.

IFileSystem fs = new FileSystem(@"C:\Temp\");

.Browse(path) returns a snapshot of directory contents.

IDirectoryContent contents = fs.Browse("C:/Windows/");

IDirectoryContent is enumerable IEnumerable<IEntry>.

foreach (IEntry entry in fs.Browse("C:/Windows/"))
    Console.WriteLine(entry.Path);

.AssertExists() asserts that directory exists. It throws DirectoryNotFound if not found.

foreach (var entry in fs.Browse("C:/Windows/").AssertExists())
    Console.WriteLine(entry.Path);

.GetEntry(path) reads a single file or directory entry. Returns null if entry is not found.

IEntry e = FileSystem.OS.GetEntry("C:/Windows/win.ini");
Console.WriteLine(e.Path);

.AssertExists() asserts that null is not returned. Throws FileNotFoundException if entry was not found.

IEntry e = FileSystem.OS.GetEntry("C:/Windows/win.ini").AssertExists();

Files can be opened for reading.

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

And for for writing.

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

Directories can be created.

fs.CreateDirectory("dir/");

Directories can be deleted.

fs.Delete("dir/", recurse: true);

Files and directories can be renamed and moved.

fs.CreateDirectory("dir/");
fs.Move("dir/", "new-name/");

And file attributes changed.

fs.SetFileAttribute("myfile", FileAttributes.ReadOnly);

Singleton

The singleton instance FileSystem.OS refers to a filesystem at the OS root.

IFileSystem fs = FileSystem.OS;

Extension method .VisitTree() visits filesystem. On root path "" FileSystem.OS returns drive letters.

foreach (var line in FileSystem.OS.VisitTree(depth: 2))
    Console.WriteLine(line);
""
├──"C:"
│  ├── "hiberfil.sys"
│  ├── "pagefile.sys"
│  ├── "swapfile.sys"
│  ├── "Documents and Settings"
│  ├── "Program Files"
│  ├── "Program Files (x86)"
│  ├── "System Volume Information"
│  ├── "Users"
│  └── "Windows10"
└──"D:"
Note

The separator character is always forward slash '/'. For example "C:/Windows/win.ini".

Extension method .PrintTo() appends the visited filesystem to text output.

FileSystem.OS.PrintTo(Console.Out, depth: 2, format: PrintTree.Format.DefaultPath);
├── C:/
│  ├── C:/hiberfil.sys
│  ├── C:/pagefile.sys
│  ├── C:/swapfile.sys
│  ├── C:/Documents and Settings/
│  ├── C:/Program Files/
│  ├── C:/Program Files (x86)/
│  ├── C:/System Volume Information/
│  ├── C:/Users/
│  └── C:/Windows/
└── D:/

On linux FileSystem.OS returns slash '/' root.

FileSystem.OS.PrintTo(Console.Out, depth: 3, format: PrintTree.Format.DefaultPath);

└──/
   ├──/bin/
   ├──/boot/
   ├──/dev/
   ├──/etc/
   ├──/lib/
   ├──/media/
   ├──/mnt/
   ├──/root/
   ├──/sys/
   ├──/usr/
   └──/var/

FileSystem.Application refers to the application's root directory.

FileSystem.Application.PrintTo(Console.Out);
""
├── "Application.dll"
├── "Application.runtimeconfig.json"
├── "Lexical.FileSystem.Abstractions.dll"
└── "Lexical.FileSystem.dll"

FileSystem.Temp refers to the running user's temp directory.

FileSystem.Temp.PrintTo(Console.Out, depth: 1);
""
├── "dmk55ohj.jjp"
├── "wrz4cms5.r2f"
└── "18e1904137f065db88dfbd23609eb877"

Singleton instances:

Name Description On Windows On Linux
FileSystem.OS Operating system root. "" ""
FileSystem.Application Running application's base directory.
FileSystem.UserProfile The user's profile folder. "C:\Users\<user>" "/home/<user>"
FileSystem.MyDocuments The My Documents folder. "C:\Users\<user>\Documents" "/home/<user>"
FileSystem.Personal A common repository for documents. "C:\Users\<user>\Documents" "/home/<user>"
FileSystem.Temp Running user's temp directory. "C:\Users\<user>\AppData\Local\Temp" "/tmp
FileSystem.Config User's cloud-sync program configuration (roaming data). "C:\Users\<user>\AppData\Roaming" "/home/<user>/.config"
FileSystem.Data User's local program data. "C:\Users\<user>\AppData\Local" "/home/<user>/.local/share"
FileSystem.ProgramData Program data that is shared with every user. "C:\ProgramData" "/usr/share"
FileSystem.Desktop User's desktop. "C:\Users\<user>\Desktop" "/home/user/Desktop"
FileSystem.MyPictures User's pictures. "C:\Users\<user>\Pictures" "/home/user/Pictures"
FileSystem.MyVideos User's videos. "C:\Users\<user>\Videos" "/home/user/Videos"
FileSystem.MyMusic User's music. "C:\Users\<user>\Music" "/home/user/Music"
FileSystem.Templates Templates. "C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Templates" "/home/user/Templates"

IFileEntry.PhysicalPath() returns physical path of file entry.

foreach(var line in FileSystem.Temp.VisitTree(depth:2))
    Console.WriteLine(line.Entry.PhysicalPath());

TreeVisitor prints physical path with PrintTree.Format.PhysicalPath flag.

FileSystem.Temp.PrintTo(
    output: Console.Out, 
    depth: 2, 
    format: PrintTree.Format.Default | PrintTree.Format.PhysicalPath);
"" [C:\Users\\user\\AppData\Local\Temp\]
├── "dmk55ohj.jjp" [C:\Users\\user\\AppData\Local\Temp\dmk55ohj.jjp]
├── "wrz4cms5.r2f" [C:\Users\\user\\AppData\Local\Temp\wrz4cms5.r2f]
└── "18e1904137f065db88dfbd23609eb877" [C:\Users\\user\\AppData\Local\Temp\18e1904137f065db88dfbd23609eb877]

Observing

Files and directories can be observed for changes.

IObserver<IEvent> observer = new Observer();
IFileSystemObserver handle = FileSystem.OS.Observe("C:/**", observer);

Observer can be used in a using scope.

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);
}
class PrintObserver : IObserver<IEvent>
{
    public void OnCompleted() => Console.WriteLine("OnCompleted");
    public void OnError(Exception error) => Console.WriteLine(error);
    public void OnNext(IEvent @event) => Console.WriteLine(@event);
}
StartEvent(C:\Users\\<i>&lt;user&gt;</i>\\AppData\Local\Temp\, 23.10.2019 16.27.01 +00:00)
CreateEvent(C:\Users\\<i>&lt;user&gt;</i>\\AppData\Local\Temp\, 23.10.2019 16.27.01 +00:00, file.dat)
ChangeEvent(C:\Users\\<i>&lt;user&gt;</i>\\AppData\Local\Temp\, 23.10.2019 16.27.01 +00:00, file.dat)
DeleteEvent(C:\Users\\<i>&lt;user&gt;</i>\\AppData\Local\Temp\, 23.10.2019 16.27.01 +00:00, file.dat)
OnCompleted

Disposing

Disposable objects can be attached to be disposed along with FileSystem.

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

// ... do work ...

// Dispose both
fs.Dispose();

Delegates can be attached to be executed at dispose of FileSystem.

IFileSystemDisposable fs = new FileSystem("")
    .AddDisposeAction(f => Console.WriteLine("Disposed"));

.BelateDispose() creates a handle that postpones dispose on .Dispose(). Actual dispose will proceed once .Dispose() is called and all belate handles are disposed. This can be used for passing the IFileSystem to a worker thread.

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();
Back to top Copyright © 2015-2020 Toni Kalajainen