using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using PARR.BLL.Domain; using PARR.BLL.Services.Interfaces; using PARR.BLL.Settings; namespace PARR.BLL.Services.Implementations { internal class FileService : IFileService { private readonly StorageSettings storageSettings; private readonly ILogger logger; public FileService(StorageSettings storageSettings, ILogger logger) { this.storageSettings = storageSettings; this.logger = logger; } public bool IsExtensionAllowed(IFormFile formFile, string[] allowedExtensions) { var extension = Path.GetExtension(formFile.FileName).ToLower(); return !string.IsNullOrEmpty(extension) && allowedExtensions.Contains(extension); } public bool IsNotExceededLimit(IFormFile formFile, int limitMb) { var fileSizeByte = formFile.Length; var fileSizeMByte = fileSizeByte / 1024.0 / 1024.0; return fileSizeMByte < limitMb; } public async Task UploadAsync(IFormFile formFile, string[] rootFolderWithoutStorage) { InitRootFolders(rootFolderWithoutStorage); //Генерим уникальное имя файла: старое имя + рандом в середину var newFileName = $"{Path.GetFileNameWithoutExtension(formFile.FileName)}-{Path.GetFileNameWithoutExtension(Path.GetRandomFileName())}{Path.GetExtension(formFile.FileName)}"; var relativePath = Path.Combine(Path.Combine(rootFolderWithoutStorage), newFileName); var absPath = Path.Combine(storageSettings.StoragePath, relativePath); if (File.Exists(absPath)) { logger.LogError($"Не могу сохранить файл, такой файл уже существует: {absPath}"); return null; } try { var origFileName = Path.GetFileName(formFile.FileName); using (var stream = new FileStream(absPath, FileMode.Create)) { await formFile.CopyToAsync(stream); logger.LogInformation($"Файл сохранен {origFileName}, {absPath}"); } return new UploadResult { FileName = origFileName, Path = relativePath }; } catch (Exception ex) { logger.LogError(ex, $"Ошибка при сохранении файла {absPath}"); return null; } } private void InitRootFolders(string[] rootFolderWithoutStorage) { if (!rootFolderWithoutStorage.Any()) return; var path = string.Empty; foreach (var item in rootFolderWithoutStorage) { path = Path.Combine(path, item); CreateDirectory(path); } } private void CreateDirectory(string relativePath) { var absolutePath = Path.Combine(storageSettings.StoragePath, relativePath); try { if (!Directory.Exists(absolutePath)) Directory.CreateDirectory(absolutePath); // не нужно ничего возвращать, при сохраненнии файла будет ошибка и ее обработаем //return true; } catch (Exception e) { logger.LogError(e, $"Не могу создать директорию: {absolutePath}"); //return false; } } public bool DeleteFile(string path) { logger.LogInformation($"Удаляю файл: {path}"); try { if (!File.Exists(path)) return true; File.Delete(path); logger.LogInformation($"Файл удален: {path}"); return true; } catch (Exception e) { logger.LogError(e, $"Ошибка при удалении файла {path}"); return false; } } } }