private static IBinaryDataAccessor OpenAutodetectFormat(string filename, IFileSystem fileSystem) { var fileLength = fileSystem.GetFileLength(filename); // First try a byte array // It's the fastest, but has the biggest memory footprint // We might not be able to fit a large file into memory, and I don't know how to open a 2GB or larger file in memory, // so we may have to fall back onto something else if (fileLength < int.MaxValue) { try { return(new InMemoryBinaryDataAccessor(fileSystem.ReadAllBytes(filename))); } catch (OutOfMemoryException) { } } // Next, try a memory mapped file system // Its speed is comparable to a byte array, but slightly slower (difference may be bigger since the InMemoryBinaryDataAccessor is the only one to support Span and Memory, which I have not yet seen the speed of first-hand) // This method might not be available depending on whether or not we have a real file system at our disposal // In the future, this may need to be feature-switchable, since we can't resize this file without disposing of it first if (fileSystem is IMemoryMappableFileSystem memoryMappableFileSystem) { var memoryMappedFile = memoryMappableFileSystem.OpenMemoryMappedFile(filename); var accessor = new MemoryMappedFileDataAccessor(memoryMappedFile, fileLength); try { // Sometimes we might not have enough memory. // When that happens, we get an IOException saying something "There are not enough memory resources available" if (memoryMappedFile.CreateViewAccessor().Capacity > -1) // Compare the capacity to -1 just to see if we get an IOException { return(accessor); } } catch (IOException) { // We can't use a MemoryMapped file. // Streams are more reliable anyway; just slower. } } // If all else fails, we can use a stream. // It's the slowest since it is not thread-safe, and the StreamBinaryDataAccessor has to use appropriate locking return(new StreamBinaryDataAccessor(fileSystem.OpenFile(filename))); }
public BinaryFile(MemoryMappedFile memoryMappedFile, int fileLength) { Accessor = new MemoryMappedFileDataAccessor(memoryMappedFile, fileLength); }