public async Task OpenFile_FallsBackToStreamIfFileOver2GB() { // Create a file that's too big // If we tried to do it in memory, it would require over 2GB of RAM. // This isn't practical and won't work on all machines, so let's use the filesystem instead // It's a safer bet we'll have over 2GB of disk space than over 2GB of RAM var provider = new PhysicalFileSystem(); var filename = "a2GBfile.bin"; if (!File.Exists(filename) || (new FileInfo(filename)).Length <= (long)int.MaxValue + 1) { using (var stream = provider.OpenFileWriteOnly(filename)) { var buffer = new byte[50000]; stream.SetLength((long)int.MaxValue + 1); stream.Seek(0, SeekOrigin.Begin); while (stream.Position < stream.Length) { await stream.WriteAsync(buffer, 0, buffer.Length); } } } // Now on with the test var file = new GenericFile(); file.EnableInMemoryLoad = true; await file.OpenFile(filename, provider); Assert.IsFalse(file.IsThreadSafe); // No thread safety indicates we're using an underlying stream }
/// <summary> /// Using the given file, auto-detects the file type and creates an instance of an appropriate object to model it. /// If no such class could be found, will return the original file /// </summary> /// <param name="file">The file for which to find a better class</param> /// <param name="duplicateFileTypeSelector">Resolves duplicate file type detections</param> /// <param name="manager">Instance of the current plugin manager</param> /// <returns>An object that represents the given file, or <paramref name="file"/> if no such class could be found.</returns> /// <exception cref="ArgumentNullException">Thrown if <see cref="file"/>, <paramref name="duplicateFileTypeSelector"/>, or <paramref name="manager"/> is null.</exception> public static async Task <object> OpenFile(GenericFile file, DuplicateMatchSelector duplicateFileTypeSelector, PluginManager manager) { if (file == null) { throw new ArgumentNullException(nameof(file)); } if (duplicateFileTypeSelector == null) { throw new ArgumentNullException(nameof(duplicateFileTypeSelector)); } if (manager == null) { throw new ArgumentNullException(nameof(manager)); } var type = await GetFileType(file, duplicateFileTypeSelector, manager); var fileOpeners = manager.GetRegisteredObjects <IFileOpener>().Where(x => x.SupportsType(type)); var genericFileOpeners = manager.GetRegisteredObjects <IFileFromGenericFileOpener>().Where(x => x.SupportsType(type)); if (type == null || !(fileOpeners.Any() || genericFileOpeners.Any()) ) { // Nothing can model the file // Re-open GenericFile so it's not readonly var newFile = new GenericFile(); await newFile.OpenFile(file.Filename, manager.CurrentFileSystem); return(newFile); } else { var openers = new List <IBaseFileOpener>(); openers.AddRange(fileOpeners); openers.AddRange(genericFileOpeners); var fileOpener = openers.OrderByDescending(x => x.GetUsagePriority(type)).First(); if (fileOpener is IFileOpener fromFileOpener) { return(await fromFileOpener.OpenFile(type, file.Filename, manager.CurrentFileSystem)); } else if (fileOpener is IFileFromGenericFileOpener fromGenericFileOpener) { return(await fromGenericFileOpener.OpenFile(type, file)); } else { throw new Exception("Unsupported IBaseFileOpener type: " + fileOpener.GetType().Name); } } }
public async Task OpenFile_InMemory() { var provider = new MemoryFileSystem(); provider.WriteAllBytes("/test.bin", new byte[] { 0, 1, 2, 3 }); var file = new GenericFile(); file.EnableInMemoryLoad = true; await file.OpenFile("/test.bin", provider); Assert.AreEqual(4, file.Length, "Failed to determine length."); Assert.IsTrue(file.Read().SequenceEqual(new byte[] { 0, 1, 2, 3 }), "Failed to read sample data."); }
public virtual async Task OpenFile(string filename, IFileSystem provider) { Filename = filename; CurrentFileSystem = provider; using (var f = new GenericFile()) { f.EnableInMemoryLoad = true; f.IsReadOnly = true; await f.OpenFile(filename, provider); Bits = new BitBlock(0); ProcessRawData(f); } }
public async Task OpenFile(string filename, IFileSystem provider) { using (var file = new GenericFile()) { await file.OpenFile(filename, provider); using (var compressed = new MemoryStream(await file.ReadAsync())) { compressed.Seek(2, SeekOrigin.Begin); using (var decompressed = new MemoryStream()) { using (var zlib = new DeflateStream(compressed, CompressionMode.Decompress)) { zlib.CopyTo(decompressed); } RawData = decompressed.ToArray(); } } } }
public async Task GetFileType_FunctionalityTest() { // Set up var manager = new PluginManager(); await manager.LoadCore(new TestCoreMod()); manager.CurrentFileSystem.WriteAllText("/test.txt", "magic data"); manager.CurrentFileSystem.WriteAllText("/test.custom", "custom data"); // Test using (var txtFile = new GenericFile()) { await txtFile.OpenFile("/test.txt", manager.CurrentFileSystem); Assert.AreEqual(typeof(OpenableTextFile).GetTypeInfo(), await IOHelper.GetFileType(txtFile, IOHelper.PickFirstDuplicateMatchSelector, manager)); } using (var customFile = new GenericFile()) { await customFile.OpenFile("/test.custom", manager.CurrentFileSystem); Assert.AreEqual(typeof(CustomTextFile).GetTypeInfo(), await IOHelper.GetFileType(customFile, IOHelper.PickFirstDuplicateMatchSelector, manager)); } }
/// <summary> /// Opens a file, auto-detecting the correct type /// </summary> /// <param name="path">Path of the file to open</param> /// <param name="duplicateFileTypeSelector">Resolves duplicate file type detections</param> /// <param name="manager">Instance of the current plugin manager</param> /// <returns>An object that represents the file at the given path</returns> /// <exception cref="ArgumentNullException">Thrown if <see cref="file"/>, <paramref name="duplicateFileTypeSelector"/>, or <paramref name="manager"/> is null.</exception> /// <exception cref="FileNotFoundException">Thrown if no file or directory could be found at the given path</exception> public static async Task <object> OpenFile(string path, DuplicateMatchSelector duplicateFileTypeSelector, PluginManager manager) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } if (duplicateFileTypeSelector == null) { throw new ArgumentNullException(nameof(duplicateFileTypeSelector)); } if (manager == null) { throw new ArgumentNullException(nameof(manager)); } if (manager.CurrentFileSystem.FileExists(path)) { using (var file = new GenericFile()) { file.IsReadOnly = true; await file.OpenFile(path, manager.CurrentFileSystem); return(await OpenFile(file, duplicateFileTypeSelector, manager)); } } else if (manager.CurrentFileSystem.DirectoryExists(path)) { return(OpenDirectory(path, duplicateFileTypeSelector, manager)); } else { throw new FileNotFoundException(Properties.Resources.IO_FileNotFound, path); } }