using Microsoft.Extensions.Logging; namespace GSS2.Core.Hardware; public class ImageStorageService { private readonly ILogger _logger; private readonly DirectoryInfo _rootDirectory; public ImageStorageService(ILogger logger, DirectoryInfo rootDirectory) { _logger = logger; _logger.LogInformation("Initialization"); _rootDirectory = rootDirectory; if (!_rootDirectory.Exists) { _rootDirectory.Create(); _logger.LogInformation("Created directory: {}", _rootDirectory.FullName); } _logger.LogInformation("Initialized"); } public async Task SaveAsync(Stream fileStream, string extension, CancellationToken ct = default) { var fileName = GenerateFileName(extension); var fullPath = GetFullPath(fileName); var directory = Path.GetDirectoryName(fullPath)!; Directory.CreateDirectory(directory); await using var file = new FileStream( fullPath, FileMode.CreateNew, FileAccess.Write, FileShare.None, 81920, useAsync: true); await fileStream.CopyToAsync(file, ct); _logger.LogInformation("File saved: {FileName}", fileName); return fileName; } public Stream OpenRead(string fileName) { var fullPath = GetFullPath(fileName); return new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read); } public bool Delete(string fileName) { var fullPath = GetFullPath(fileName); if (!File.Exists(fullPath)) return false; File.Delete(fullPath); return true; } private string GenerateFileName(string extension) { var guid = Guid.NewGuid().ToString("N"); return $"{guid}{extension}"; } public string GetFullPath(string fileName) { var level1 = fileName.Substring(0, 2); var level2 = fileName.Substring(2, 2); return Path.Combine(_rootDirectory.FullName, level1, level2, fileName); } }