// /*************************************************************************** // Aaru Data Preservation Suite // ---------------------------------------------------------------------------- // // Filename : DataFile.cs // Author(s) : Natalia Portillo // // Component : Core algorithms. // // --[ Description ] ---------------------------------------------------------- // // Abstracts writing to files. // // --[ License ] -------------------------------------------------------------- // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General public License for more details. // // You should have received a copy of the GNU General public License // along with this program. If not, see . // // ---------------------------------------------------------------------------- // Copyright © 2011-2024 Natalia Portillo // ****************************************************************************/ using System.Diagnostics.CodeAnalysis; using System.IO; using Aaru.Console; using Aaru.Helpers; namespace Aaru.Core; /// Abstracts a datafile with a block based interface [SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")] [SuppressMessage("ReSharper", "UnusedMember.Global")] public sealed class DataFile { readonly FileStream _dataFs; /// Opens, or create, a new file /// File public DataFile(string outputFile) => _dataFs = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.ReadWrite); /// Current file position public long Position => _dataFs.Position; /// Closes the file public void Close() => _dataFs?.Close(); /// Reads bytes at current position /// Array to place read data within /// Offset of where data will be read /// How many bytes to read /// How many bytes were read public int Read(byte[] array, int offset, int count) => _dataFs.EnsureRead(array, offset, count); /// Seeks to the specified block /// Block to seek to /// Block size in bytes /// Position public long Seek(ulong block, ulong blockSize) => _dataFs.Seek((long)(block * blockSize), SeekOrigin.Begin); /// Seeks to specified byte position /// Byte position /// Where to count for position /// Position public long Seek(ulong offset, SeekOrigin origin) => _dataFs.Seek((long)offset, origin); /// Seeks to specified byte position /// Byte position /// Where to count for position /// Position public long Seek(long offset, SeekOrigin origin) => _dataFs.Seek(offset, origin); /// Writes data at current position /// Data public void Write(byte[] data) => Write(data, 0, data.Length); /// Writes data at current position /// Data /// Offset of data from where to start taking data to write /// How many bytes to write public void Write(byte[] data, int offset, int count) => _dataFs.Write(data, offset, count); /// Writes data at specified block /// Data /// Block /// Bytes per block public void WriteAt(byte[] data, ulong block, uint blockSize) => WriteAt(data, block, blockSize, 0, data.Length); /// Writes data at specified block /// Data /// Block /// Bytes per block /// Offset of data from where to start taking data to write /// How many bytes to write public void WriteAt(byte[] data, ulong block, uint blockSize, int offset, int count) { _dataFs.Seek((long)(block * blockSize), SeekOrigin.Begin); _dataFs.Write(data, offset, count); } /// Writes data to a newly created file /// Who asked the file to be written (class, plugin, etc.) /// Data to write /// First part of the file name /// Last part of the file name /// What is the data about? public static void WriteTo(string who, string outputPrefix, string outputSuffix, string whatWriting, byte[] data) { if(!string.IsNullOrEmpty(outputPrefix) && !string.IsNullOrEmpty(outputSuffix)) WriteTo(who, outputPrefix + outputSuffix, data, whatWriting); } /// Writes data to a newly created file /// Who asked the file to be written (class, plugin, etc.) /// Filename to create /// Data to write /// What is the data about? /// If set to true overwrites the file, does nothing otherwise public static void WriteTo(string who, string filename, byte[] data, string whatWriting = null, bool overwrite = false) { if(string.IsNullOrEmpty(filename)) return; if(File.Exists(filename)) { if(overwrite) File.Delete(filename); else { AaruConsole.ErrorWriteLine(Localization.Core.Not_overwriting_file_0, filename); return; } } try { AaruConsole.DebugWriteLine(who, string.Format(Localization.Core.Writing_0_to_1, whatWriting, filename)); var outputFs = new FileStream(filename, FileMode.CreateNew); outputFs.Write(data, 0, data.Length); outputFs.Close(); } catch { AaruConsole.ErrorWriteLine(Localization.Core.Unable_to_write_file_0, filename); } } }