diff --git a/AsbCloudApp/Repositories/IFileStorageRepository.cs b/AsbCloudApp/Repositories/IFileStorageRepository.cs index 72c11d21..68ce51e9 100644 --- a/AsbCloudApp/Repositories/IFileStorageRepository.cs +++ b/AsbCloudApp/Repositories/IFileStorageRepository.cs @@ -12,17 +12,12 @@ namespace AsbCloudApp.Repositories /// public interface IFileStorageRepository { - /// - /// Директория хранения файлов - /// - string RootPath { get; } - /// /// Получение длинны фала и проверка его наличия, если отсутствует падает исключение /// /// /// - long GetLengthFile(string srcFilePath); + long GetFileLength(string srcFilePath); /// /// Перемещение файла @@ -34,29 +29,24 @@ namespace AsbCloudApp.Repositories /// /// Копирование файла /// + /// + /// + /// /// - Task CopyFileAsync(string filePath, Stream fileStream, CancellationToken token); + Task SaveFileAsync(string filePathRec, Stream fileStreamSrc, CancellationToken token); /// /// Удаление файла /// - /// - void DeleteFile(string fileName); - - /// - /// Проверка наличия файла - /// - /// - /// - /// - bool FileExists(string fullPath, string fileName); + /// + void DeleteFile(IEnumerable filesName); /// /// Удаление всех файлов с диска о которых нет информации в базе /// /// /// - int DeleteFilesNotExistStorage(int idWell, IEnumerable idsFiles); + int DeleteFilesNotList(int idWell, IEnumerable idsFiles); /// /// Вывод списка всех файлов из базы, для которых нет файла на диске @@ -64,7 +54,7 @@ namespace AsbCloudApp.Repositories /// /// /// - IEnumerable GetListFilesNotDisc(int idWell, IEnumerable files); + IEnumerable GetListFilesNotDisc(IEnumerable files); /// /// Получение пути к файлу @@ -75,6 +65,16 @@ namespace AsbCloudApp.Repositories /// /// string MakeFilePath(int idWell, int idCategory, string fileFullName, int fileId); + + /// + /// Получить путь для скачивания + /// + /// + /// + /// + /// + /// + string GetUrl(int idWell, int idCategory, int idFile, string dotExtention); } #nullable disable } diff --git a/AsbCloudApp/Services/FileService.cs b/AsbCloudApp/Services/FileService.cs index 34cb1fe5..d16006e1 100644 --- a/AsbCloudApp/Services/FileService.cs +++ b/AsbCloudApp/Services/FileService.cs @@ -6,6 +6,8 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using static Npgsql.PostgresTypes.PostgresCompositeType; +using static System.Net.WebRequestMethods; namespace AsbCloudApp.Services { @@ -44,7 +46,7 @@ namespace AsbCloudApp.Services { destinationFileName = Path.GetFileName(destinationFileName); srcFilePath = Path.GetFullPath(srcFilePath); - var fileSize = fileStorageRepository.GetLengthFile(srcFilePath); + var fileSize = fileStorageRepository.GetFileLength(srcFilePath); //save info to db var dto = new FileInfoDto { @@ -91,7 +93,7 @@ namespace AsbCloudApp.Services //save stream to disk string filePath = fileStorageRepository.MakeFilePath(idWell, idCategory, fileFullName, fileId); - await fileStorageRepository.CopyFileAsync(filePath, fileStream, token); + await fileStorageRepository.SaveFileAsync(filePath, fileStream, token); return await GetInfoAsync(fileId, token); } @@ -111,7 +113,6 @@ namespace AsbCloudApp.Services var relativePath = GetUrl(dto.IdWell, dto.IdCategory, dto.Id, ext); var fullPath = Path.GetFullPath(relativePath); - fileStorageRepository.FileExists(fullPath, relativePath); return dto; } @@ -141,27 +142,12 @@ namespace AsbCloudApp.Services if (files is null || !files.Any()) return 0; - foreach (var file in files) - { - var fileName = GetUrl(file.IdWell, file.IdCategory, file.Id, Path.GetExtension(file.Name)); - fileStorageRepository.DeleteFile(fileName); - } + var filesName = files.Select(x => GetUrl(x.IdWell, x.IdCategory, x.Id, Path.GetExtension(x.Name))); + fileStorageRepository.DeleteFile(filesName); return files.Any() ? 1 : 0; } - /// - /// получить путь для скачивания - /// - /// - /// - public async Task GetUrl(int idFile) - { - var fileInfo = await fileRepository.GetOrDefaultAsync(idFile, CancellationToken.None).ConfigureAwait(false); - - return GetUrl(fileInfo.IdWell, fileInfo.IdCategory, fileInfo.Id, Path.GetExtension(fileInfo.Name)); - } - /// /// получить путь для скачивания /// @@ -179,7 +165,7 @@ namespace AsbCloudApp.Services /// /// public string GetUrl(int idWell, int idCategory, int idFile, string dotExtention) => - Path.Combine(fileStorageRepository.RootPath, idWell.ToString(), idCategory.ToString(), $"{idFile}{dotExtention}"); + fileStorageRepository.GetUrl(idWell, idCategory, idFile, dotExtention); /// /// пометить метку файла как удаленную @@ -207,7 +193,6 @@ namespace AsbCloudApp.Services var ext = Path.GetExtension(entity.Name); var relativePath = GetUrl(entity.IdWell, entity.IdCategory, entity.Id, ext); var fullPath = Path.GetFullPath(relativePath); - fileStorageRepository.FileExists(fullPath, relativePath); } return result; @@ -327,7 +312,7 @@ namespace AsbCloudApp.Services IdWell = idWell }, token); - var result = await Task.FromResult(fileStorageRepository.DeleteFilesNotExistStorage(idWell, files.Select(x => x.Id))); + var result = await Task.FromResult(fileStorageRepository.DeleteFilesNotList(idWell, files.Select(x => x.Id))); return result; } @@ -335,6 +320,7 @@ namespace AsbCloudApp.Services /// Вывод списка всех файлов из базы, для которых нет файла на диске /// /// + /// /// public async Task> GetListFilesNotDisc(int idWell, CancellationToken token) { @@ -344,7 +330,7 @@ namespace AsbCloudApp.Services IdWell = idWell }, token); - var result = fileStorageRepository.GetListFilesNotDisc(idWell, files); + var result = fileStorageRepository.GetListFilesNotDisc(files); return result; } } diff --git a/AsbCloudInfrastructure/Repository/FileStorageRepository.cs b/AsbCloudInfrastructure/Repository/FileStorageRepository.cs index 2b1f84f1..37a041b7 100644 --- a/AsbCloudInfrastructure/Repository/FileStorageRepository.cs +++ b/AsbCloudInfrastructure/Repository/FileStorageRepository.cs @@ -14,31 +14,33 @@ namespace AsbCloudInfrastructure.Repository #nullable enable public class FileStorageRepository : IFileStorageRepository { - public string RootPath { get; private set; } + /// + /// Директория хранения файлов + /// + private readonly string RootPath = "files"; public FileStorageRepository() { - RootPath = "files"; } - public async Task CopyFileAsync(string filePath, Stream fileStream, CancellationToken token) + public async Task SaveFileAsync(string filePathRec, Stream fileStreamSrc, CancellationToken token) { - CreateDirectory(filePath); - using var newfileStream = new FileStream(filePath, FileMode.Create); - await fileStream.CopyToAsync(newfileStream, token).ConfigureAwait(false); + CreateDirectory(filePathRec); + using var newfileStream = new FileStream(filePathRec, FileMode.Create); + await fileStreamSrc.CopyToAsync(newfileStream, token).ConfigureAwait(false); } - public void DeleteFile(string fileName) + public void DeleteFile(IEnumerable filesName) { - if (File.Exists(fileName)) - File.Delete(fileName); + foreach (var fileName in filesName) + { + if (File.Exists(fileName)) + File.Delete(fileName); + } } - public long GetLengthFile(string srcFilePath) + public long GetFileLength(string srcFilePath) { - if (!File.Exists(srcFilePath)) - throw new ArgumentInvalidException($"file {srcFilePath} doesn't exist", nameof(srcFilePath)); - var sysFileInfo = new FileInfo(srcFilePath); return sysFileInfo.Length; } @@ -49,51 +51,50 @@ namespace AsbCloudInfrastructure.Repository File.Move(srcFilePath, filePath); } - public bool FileExists(string fullPath, string fileName) - { - if (!File.Exists(fullPath)) - throw new FileNotFoundException("not found", fileName); - - return true; - } - public string MakeFilePath(int idWell, int idCategory, string fileFullName, int fileId) { return Path.Combine(RootPath, $"{idWell}", $"{idCategory}", $"{fileId}" + $"{Path.GetExtension(fileFullName)}"); } - public int DeleteFilesNotExistStorage(int idWell, IEnumerable idsFiles) + public int DeleteFilesNotList(int idWell, IEnumerable idsFilesList) { var allFilesPath = GetFilesPath(idWell); - var resutl = 0; + var result = 0; foreach (var filePath in allFilesPath) { - var idFile = Path.GetFileNameWithoutExtension(filePath); - if (!idsFiles.Any(x => x.ToString() == idFile)) + if (int.TryParse(Path.GetFileNameWithoutExtension(filePath), out int idFile) + || !idsFilesList.Any(x => x == idFile)) { File.Delete(filePath); - resutl++; + result++; + } + } + + return result; + } + + public IEnumerable GetListFilesNotDisc(IEnumerable files) + { + var resutl = new List(); + var groupFiles = files.GroupBy(x => x.IdWell); + + foreach (var itemGroupFiles in groupFiles) + { + var idsFilesStorage = GetIdsFiles(itemGroupFiles.Key); + foreach (var file in files) + { + if (!idsFilesStorage.Any(x => x == file.Id)) + resutl.Add(file); } } return resutl; } - public IEnumerable GetListFilesNotDisc(int idWell, IEnumerable files) - { - var resutl = new List(); - var idsFilesStorage = GetIdsFiles(idWell); - - foreach (var file in files) - { - if (!idsFilesStorage.Any(x => x == file.Id)) - resutl.Add(file); - } - - return resutl; - } + public string GetUrl(int idWell, int idCategory, int idFile, string dotExtention) => + Path.Combine(RootPath, idWell.ToString(), idCategory.ToString(), $"{idFile}{dotExtention}"); private IEnumerable GetIdsFiles(int idWell) { @@ -102,8 +103,8 @@ namespace AsbCloudInfrastructure.Repository foreach (var filePath in allFilesPath) { - var idFileStr = Path.GetFileNameWithoutExtension(filePath); - result.Add(Convert.ToInt32(idFileStr)); + int.TryParse(Path.GetFileNameWithoutExtension(filePath), out int idFile); + result.Add(idFile); } return result; diff --git a/AsbCloudWebApi.Tests/ServicesTests/FileServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/FileServiceTest.cs index 5710f40b..cf35bcab 100644 --- a/AsbCloudWebApi.Tests/ServicesTests/FileServiceTest.cs +++ b/AsbCloudWebApi.Tests/ServicesTests/FileServiceTest.cs @@ -134,8 +134,6 @@ namespace AsbCloudWebApi.Tests.ServicesTests var storageRepositoryMock = new Mock(); - storageRepositoryMock.Setup(x => x.RootPath).Returns("files"); - fileService = new FileService(repositoryMock.Object, storageRepositoryMock.Object); } diff --git a/AsbCloudWebApi/Controllers/FileController.cs b/AsbCloudWebApi/Controllers/FileController.cs index 1c29b902..85c095a3 100644 --- a/AsbCloudWebApi/Controllers/FileController.cs +++ b/AsbCloudWebApi/Controllers/FileController.cs @@ -7,6 +7,8 @@ using Microsoft.AspNetCore.Mvc; using System.IO; using System.Threading; using System.Threading.Tasks; +using System.Text; +using static System.Net.WebRequestMethods; namespace AsbCloudWebApi.Controllers { @@ -120,9 +122,10 @@ namespace AsbCloudWebApi.Controllers try { var fileInfo = await fileService.GetInfoAsync(fileId, token); - var relativePath = fileService.GetUrl(fileInfo); - return PhysicalFile(Path.GetFullPath(relativePath), "application/octet-stream", fileInfo.Name); + + var fileStream = new FileStream(Path.GetFullPath(relativePath), FileMode.Open); + return File(fileStream, "application/octet-stream", fileInfo.Name); } catch (FileNotFoundException ex) {