/// <summary> /// Function to open the editor file. /// </summary> /// <param name="path">Path to the editor file.</param> public static void Open(string path) { var packFileSystem = new GorgonFileSystem(); FileChanged = false; // Add the new file system as a mount point. var plugIns = from plugIn in Gorgon.PlugIns where plugIn is GorgonFileSystemProviderPlugIn && !PlugIns.IsDisabled(plugIn) select plugIn; foreach (var plugIn in plugIns) { packFileSystem.Providers.LoadProvider(plugIn.Name); } if (!packFileSystem.Providers.Any(item => item.CanReadFile(path))) { throw new FileLoadException(string.Format(APIResources.GOREDIT_ERR_NO_READ_PROVIDERS, Path.GetFileName(path))); } packFileSystem.Mount(path); try { // Remove our previous scratch data. ResetFile(); // At this point we should have a clean scratch area, so all files will exist in the packed file. // Unpack the file structure so we can work with it. var directories = packFileSystem.FindDirectories("*", true); var files = packFileSystem.FindFiles("*", true); // Create our directories. foreach (var directory in directories) { ScratchArea.ScratchFiles.CreateDirectory(directory.FullPath); } // Copy our files. foreach (var file in files) { using (var inputStream = packFileSystem.OpenStream(file, false)) { using (var outputStream = ScratchArea.ScratchFiles.OpenStream(file.FullPath, true)) { inputStream.CopyTo(outputStream); } } } FilePath = string.Empty; Filename = Path.GetFileName(path); // Load the meta data if it exists. EditorMetaDataFile.Load(); // If we can't write the file, then leave the editor file path as blank. // If the file path is blank, then the Save As function will be triggered if we attempt to save so we // can save it in a format that we DO understand. This is of course assuming we have any plug-ins loaded // that will allow us to save. if (GetWriterPlugIn(path) != null) { FilePath = path; } } catch { // We have a problem, reset whatever changes we've made. ResetFile(); throw; } finally { // At this point we don't need this file system any more. We'll // be using our scratch system instead. packFileSystem.Clear(); } }
/// <summary> /// The main entry point for the application. /// </summary> private static void Main() { _log = new GorgonLog("FolderFileSystem", "Tape_Worm"); _log.LogStart(); try { Console.WindowHeight = 26.Max(Console.WindowHeight); Console.BufferHeight = Console.WindowHeight; // Create a new file system. _fileSystem = new GorgonFileSystem(_log); // Set the following directory as root on the virtual file system. // To mount a directory we need to put in the trailing slash. // // If we wanted to, we could mount a directory as a sub directory of // the root of the virtual file system. For example, mounting the // directory D:\Dir with Mount(@"D:\Dir", "/VFSDir"); would mount the // contents of the D:\Dir directory under /VFSDir. // // It's also important to point out that the old Gorgon "file system" // would load files from the system into memory when mounting a // directory. While this version only loads directory and file // information when mounting. This is considerably more efficient. string physicalPath = GetResourcePath(@"FolderSystem\"); _fileSystem.Mount(physicalPath); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("This example will mount a physical file system directory as the root of a"); Console.WriteLine("virtual file system. The virtual file system is capable of mounting various"); Console.WriteLine("types of data such as a zip file, a file system folder, etc... as the root or a"); Console.WriteLine("sub directory. You can even mount a zip file as the root, and a physical file"); Console.WriteLine("system directory as a virtual sub directory in the same virtual file system and"); Console.WriteLine("access them as a single unified file system."); Console.Write("\nMounted: "); Console.ForegroundColor = ConsoleColor.Cyan; Console.Write("'{0}'", physicalPath.Ellipses(Console.WindowWidth - 20, true)); Console.ForegroundColor = ConsoleColor.White; Console.Write(" as "); Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("'/'\n"); Console.ForegroundColor = ConsoleColor.White; // Get a count of all sub directories and files under the root directory. IGorgonVirtualDirectory[] directoryList = _fileSystem.FindDirectories("*").ToArray(); // Display directories. Console.WriteLine("Virtual file system contents:"); for (int i = -1; i < directoryList.Length; i++) { IGorgonVirtualDirectory directory = _fileSystem.RootDirectory; // Go into the sub directories under root. if (i > -1) { directory = directoryList[i]; } Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("{0}", directory.FullPath); Console.ForegroundColor = ConsoleColor.Yellow; foreach (IGorgonVirtualFile file in directory.Files) { Console.Write(" {0}", file.Name); // Align the size to the same place. Console.CursorLeft = 65; Console.WriteLine("{0}", file.Size.FormatMemory()); } } Console.ResetColor(); Console.WriteLine("\nPress any key to close."); Console.ReadKey(); } catch (Exception ex) { ex.Catch(_ => { Console.Clear(); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Exception:\n{0}\n\nStack Trace:{1}", _.Message, _.StackTrace); Console.ResetColor(); #if DEBUG Console.ReadKey(); #endif }, _log); } finally { _log.LogEnd(); } }
/// <summary> /// The main entry point for the application. /// </summary> private static void Main() { _log = new GorgonLog("ZipFileSystem", "Tape_Worm"); _log.LogStart(); // Create the plugin assembly cache. _pluginAssemblies = new GorgonMefPlugInCache(_log); // Create the plugin service. _pluginService = new GorgonMefPlugInService(_pluginAssemblies); try { Console.WindowHeight = 28; Console.BufferHeight = Console.WindowHeight; Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("This example will mount a zip file as the root of a virtual file system. The"); Console.WriteLine("virtual file system is capable of mounting various types of data such as a zip,"); Console.WriteLine("a file system folder, etc... as the root or a sub directory. You can even"); Console.WriteLine("mount a zip file as the root, and a physical file system directory as a virtual"); Console.WriteLine("sub directory in the same virtual file system and access them as a single"); Console.WriteLine("unified file system."); // Unlike the folder file system example, we need to load // a provider to handle zip files before trying to mount // one. if (!LoadZipProviderPlugIn()) { return; } // Set the following zip file as root on the virtual file system. // // If we wanted to, we could mount a zip file as a sub directory of // the root of the virtual file system. For example, mounting the // directory D:\Dir\zipFile.zip with Mount(@"D:\Dir", "/VFSDir"); would mount // the contents of the D:\Dir\zipFile.zip directory under /VFSDir. // // It's also important to point out that the old Gorgon "file system" // would load files from the system into memory when mounting a // directory. While this version only loads directory and file // information when mounting. This is considerably more efficient. string physicalPath = GetResourcePath(@"FileSystem.zip"); _fileSystem.Mount(physicalPath); Console.Write("\nMounted: "); Console.ForegroundColor = ConsoleColor.Cyan; Console.Write("'{0}'", physicalPath.Ellipses(Console.WindowWidth - 20, true)); Console.ForegroundColor = ConsoleColor.White; Console.Write(" as "); Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("'/'\n"); Console.ForegroundColor = ConsoleColor.White; // Get a count of all sub directories and files under the root directory. IGorgonVirtualDirectory[] directoryList = _fileSystem.FindDirectories("*").ToArray(); // Display directories. Console.WriteLine("Virtual file system contents:"); for (int i = -1; i < directoryList.Length; i++) { IGorgonVirtualDirectory directory = _fileSystem.RootDirectory; // Go into the sub directories under root. if (i > -1) { directory = directoryList[i]; } Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("{0}", directory.FullPath); Console.ForegroundColor = ConsoleColor.Yellow; foreach (IGorgonVirtualFile file in directory.Files) { Console.Write(" {0}", file.Name); // Align the size to the same place. Console.CursorLeft = 65; Console.WriteLine("{0}", file.Size.FormatMemory()); } } Console.ResetColor(); Console.WriteLine("\nPress any key to close."); Console.ReadKey(); } catch (Exception ex) { ex.Catch(_ => { Console.Clear(); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Exception:\n{0}\n\nStack Trace:{1}", _.Message, _.StackTrace); Console.ResetColor(); #if DEBUG Console.ReadKey(); #endif }); } finally { // Always dispose the cache to clean up the temporary app domain it creates. _pluginAssemblies.Dispose(); _log.LogEnd(); } }
/// <summary> /// Function to copy the file system data from a file system file. /// </summary> /// <param name="fileSystemFile">The file system file to copy.</param> /// <param name="provider">The provider to use.</param> /// <param name="fileSystemDir">The workspace directory to copy the files into.</param> /// <returns>The path to the metadata file.</returns> private async Task <FileInfo> CopyFileSystemAsync(FileInfo fileSystemFile, IGorgonFileSystemProvider provider, DirectoryInfo fileSystemDir) { IGorgonFileSystem fileSystem = new GorgonFileSystem(provider, Program.Log); fileSystem.Mount(fileSystemFile.FullName); IGorgonVirtualFile metaData = fileSystem.GetFile(Path.Combine("/", CommonEditorConstants.EditorMetadataFileName)); // Get all directories and replicate them. IEnumerable <IGorgonVirtualDirectory> directories = fileSystem.FindDirectories("/", "*") .OrderBy(item => item.FullPath.Length); foreach (IGorgonVirtualDirectory directory in directories) { var dirInfo = new DirectoryInfo(Path.Combine(fileSystemDir.FullName, directory.FullPath.FormatDirectory(Path.DirectorySeparatorChar).Substring(1))); if (dirInfo.Exists) { continue; } dirInfo.Create(); } // Copy all files into the directories we just created. var files = fileSystem.FindFiles("/", "*") .Where(item => item != metaData) .OrderByDescending(item => item.Size) .ToList(); int maxJobCount = (Environment.ProcessorCount * 2).Min(32).Max(1); int filesPerJob = (int)((float)files.Count / maxJobCount).FastCeiling(); var jobs = new List <Task>(); if ((files.Count <= 100) || (maxJobCount < 2)) { filesPerJob = files.Count; } Program.Log.Print($"Copying file system. {filesPerJob} files will be copied in a single job.", LoggingLevel.Verbose); void CopyFile(FileCopyJob job) { foreach (IGorgonVirtualFile file in job.Files) { var fileInfo = new FileInfo(Path.Combine(fileSystemDir.FullName, file.Directory.FullPath.FormatDirectory(Path.DirectorySeparatorChar).Substring(1), file.Name)); using (Stream readStream = file.OpenStream()) using (Stream writeStream = fileInfo.OpenWrite()) { readStream.CopyToStream(writeStream, (int)readStream.Length, job.ReadBuffer); } } } // Build up the tasks for our jobs. while (files.Count > 0) { var jobData = new FileCopyJob(); // Copy the file information to the file copy job data. int length = filesPerJob.Min(files.Count); for (int i = 0; i < length; ++i) { jobData.Files.Add(files[i]); } files.RemoveRange(0, length); jobs.Add(Task.Run(() => CopyFile(jobData))); } Program.Log.Print($"{jobs.Count} jobs running for file copy from '{fileSystemFile.FullName}'.", LoggingLevel.Verbose); // Wait for the file copy to finish. await Task.WhenAll(jobs); var metaDataOutput = new FileInfo(Path.Combine(fileSystemDir.FullName, CommonEditorConstants.EditorMetadataFileName)); if (metaData == null) { Program.Log.Print($"'{fileSystemFile.FullName}' has no metadata. A new metadata index will be generated.", LoggingLevel.Verbose); return(metaDataOutput); } Program.Log.Print($"'{fileSystemFile.FullName}' has metadata. Copying to the .", LoggingLevel.Verbose); byte[] writeBuffer = new byte[81920]; using (Stream readStream = metaData.OpenStream()) using (Stream writeStream = metaDataOutput.OpenWrite()) { readStream.CopyToStream(writeStream, (int)readStream.Length, writeBuffer); } metaDataOutput.Attributes = FileAttributes.Archive | FileAttributes.Normal; metaDataOutput.Refresh(); return(metaDataOutput); }
/// <summary> /// The main entry point for the application. /// </summary> static void Main() { try { Console.WindowHeight = 28; Console.BufferHeight = Console.WindowHeight; // Create a new file system. _fileSystem = new GorgonFileSystem(); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("This example will mount a zip file as the root of a virtual file system. The"); Console.WriteLine("virtual file system is capable of mounting various types of data such as a zip,"); Console.WriteLine("a file system folder, etc... as the root or a sub directory. You can even"); Console.WriteLine("mount a zip file as the root, and a physical file system directory as a virtual"); Console.WriteLine("sub directory in the same virtual file system and access them as a single"); Console.WriteLine("unified file system."); // Unlike the folder file system example, we need to load // a provider to handle zip files before trying to mount // one. if (!LoadZipProviderPlugIn()) { return; } // Set the following zip file as root on the virtual file system. // // If we wanted to, we could mount a zip file as a sub directory of // the root of the virtual file system. For example, mounting the // directory D:\Dir\zipFile.zip with Mount(@"D:\Dir", "/VFSDir"); would mount // the contents of the D:\Dir\zipFile.zip directory under /VFSDir. // // It's also important to point out that the old Gorgon "file system" // would load files from the system into memory when mounting a // directory. While this version only loads directory and file // information when mounting. This is considerably more efficient. var physicalPath = GetResourcePath(@"FileSystem.zip"); _fileSystem.Mount(physicalPath); Console.Write("\nMounted: "); Console.ForegroundColor = ConsoleColor.Cyan; Console.Write("'{0}'", physicalPath.Ellipses(Console.WindowWidth - 20, true)); Console.ForegroundColor = ConsoleColor.White; Console.Write(" as "); Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("'/'\n"); Console.ForegroundColor = ConsoleColor.White; // Get a count of all sub directories and files under the root directory. var directoryList = _fileSystem.FindDirectories("*", true).ToArray(); // Display directories. Console.WriteLine("Virtual file system contents:"); for (int i = -1; i < directoryList.Length; i++) { GorgonFileSystemDirectory directory = _fileSystem.RootDirectory; // Go into the sub directories under root. if (i > -1) { directory = directoryList[i]; } Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("{0}", directory.FullPath); Console.ForegroundColor = ConsoleColor.Yellow; foreach (var file in directory.Files) { Console.Write(" {0}", file.Name); // Align the size to the same place. Console.CursorLeft = 65; Console.WriteLine("{0}", file.Size.FormatMemory()); } } Console.ResetColor(); Console.WriteLine("\nPress any key to close."); Console.ReadKey(); } catch (Exception ex) { // Catch all exceptions here. If we had logging for the application enabled, then this // would record the exception in the log. GorgonException.Catch(ex, () => { Console.Clear(); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Exception:\n{0}\n\nStack Trace:{1}", ex.Message, ex.StackTrace); Console.ResetColor(); #if DEBUG Console.ReadKey(); #endif }); } }