#6385536 Замечания

This commit is contained in:
ai.astrakhantsev 2022-10-11 14:42:04 +05:00
parent 0b2ae0b361
commit b54de8fe06
5 changed files with 76 additions and 88 deletions

View File

@ -12,17 +12,12 @@ namespace AsbCloudApp.Repositories
/// </summary> /// </summary>
public interface IFileStorageRepository public interface IFileStorageRepository
{ {
/// <summary>
/// Директория хранения файлов
/// </summary>
string RootPath { get; }
/// <summary> /// <summary>
/// Получение длинны фала и проверка его наличия, если отсутствует падает исключение /// Получение длинны фала и проверка его наличия, если отсутствует падает исключение
/// </summary> /// </summary>
/// <param name="srcFilePath"></param> /// <param name="srcFilePath"></param>
/// <returns></returns> /// <returns></returns>
long GetLengthFile(string srcFilePath); long GetFileLength(string srcFilePath);
/// <summary> /// <summary>
/// Перемещение файла /// Перемещение файла
@ -34,29 +29,24 @@ namespace AsbCloudApp.Repositories
/// <summary> /// <summary>
/// Копирование файла /// Копирование файла
/// </summary> /// </summary>
/// <param name="filePathRec"></param>
/// <param name="fileStreamSrc"></param>
/// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task CopyFileAsync(string filePath, Stream fileStream, CancellationToken token); Task SaveFileAsync(string filePathRec, Stream fileStreamSrc, CancellationToken token);
/// <summary> /// <summary>
/// Удаление файла /// Удаление файла
/// </summary> /// </summary>
/// <param name="fileName"></param> /// <param name="filesName"></param>
void DeleteFile(string fileName); void DeleteFile(IEnumerable<string> filesName);
/// <summary>
/// Проверка наличия файла
/// </summary>
/// <param name="fullPath"></param>
/// <param name="fileName"></param>
/// <returns></returns>
bool FileExists(string fullPath, string fileName);
/// <summary> /// <summary>
/// Удаление всех файлов с диска о которых нет информации в базе /// Удаление всех файлов с диска о которых нет информации в базе
/// </summary> /// </summary>
/// <param name="idWell"></param> /// <param name="idWell"></param>
/// <param name="idsFiles"></param> /// <param name="idsFiles"></param>
int DeleteFilesNotExistStorage(int idWell, IEnumerable<int> idsFiles); int DeleteFilesNotList(int idWell, IEnumerable<int> idsFiles);
/// <summary> /// <summary>
/// Вывод списка всех файлов из базы, для которых нет файла на диске /// Вывод списка всех файлов из базы, для которых нет файла на диске
@ -64,7 +54,7 @@ namespace AsbCloudApp.Repositories
/// <param name="idWell"></param> /// <param name="idWell"></param>
/// <param name="files"></param> /// <param name="files"></param>
/// <returns></returns> /// <returns></returns>
IEnumerable<FileInfoDto> GetListFilesNotDisc(int idWell, IEnumerable<FileInfoDto> files); IEnumerable<FileInfoDto> GetListFilesNotDisc(IEnumerable<FileInfoDto> files);
/// <summary> /// <summary>
/// Получение пути к файлу /// Получение пути к файлу
@ -75,6 +65,16 @@ namespace AsbCloudApp.Repositories
/// <param name="fileId"></param> /// <param name="fileId"></param>
/// <returns></returns> /// <returns></returns>
string MakeFilePath(int idWell, int idCategory, string fileFullName, int fileId); string MakeFilePath(int idWell, int idCategory, string fileFullName, int fileId);
/// <summary>
/// Получить путь для скачивания
/// </summary>
/// <param name="idWell"></param>
/// <param name="idCategory"></param>
/// <param name="idFile"></param>
/// <param name="dotExtention"></param>
/// <returns></returns>
string GetUrl(int idWell, int idCategory, int idFile, string dotExtention);
} }
#nullable disable #nullable disable
} }

View File

@ -6,6 +6,8 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using static Npgsql.PostgresTypes.PostgresCompositeType;
using static System.Net.WebRequestMethods;
namespace AsbCloudApp.Services namespace AsbCloudApp.Services
{ {
@ -44,7 +46,7 @@ namespace AsbCloudApp.Services
{ {
destinationFileName = Path.GetFileName(destinationFileName); destinationFileName = Path.GetFileName(destinationFileName);
srcFilePath = Path.GetFullPath(srcFilePath); srcFilePath = Path.GetFullPath(srcFilePath);
var fileSize = fileStorageRepository.GetLengthFile(srcFilePath); var fileSize = fileStorageRepository.GetFileLength(srcFilePath);
//save info to db //save info to db
var dto = new FileInfoDto { var dto = new FileInfoDto {
@ -91,7 +93,7 @@ namespace AsbCloudApp.Services
//save stream to disk //save stream to disk
string filePath = fileStorageRepository.MakeFilePath(idWell, idCategory, fileFullName, fileId); 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); return await GetInfoAsync(fileId, token);
} }
@ -111,7 +113,6 @@ namespace AsbCloudApp.Services
var relativePath = GetUrl(dto.IdWell, dto.IdCategory, dto.Id, ext); var relativePath = GetUrl(dto.IdWell, dto.IdCategory, dto.Id, ext);
var fullPath = Path.GetFullPath(relativePath); var fullPath = Path.GetFullPath(relativePath);
fileStorageRepository.FileExists(fullPath, relativePath);
return dto; return dto;
} }
@ -141,27 +142,12 @@ namespace AsbCloudApp.Services
if (files is null || !files.Any()) if (files is null || !files.Any())
return 0; return 0;
foreach (var file in files) var filesName = files.Select(x => GetUrl(x.IdWell, x.IdCategory, x.Id, Path.GetExtension(x.Name)));
{ fileStorageRepository.DeleteFile(filesName);
var fileName = GetUrl(file.IdWell, file.IdCategory, file.Id, Path.GetExtension(file.Name));
fileStorageRepository.DeleteFile(fileName);
}
return files.Any() ? 1 : 0; return files.Any() ? 1 : 0;
} }
/// <summary>
/// получить путь для скачивания
/// </summary>
/// <param name="idFile"></param>
/// <returns></returns>
public async Task<string> 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));
}
/// <summary> /// <summary>
/// получить путь для скачивания /// получить путь для скачивания
/// </summary> /// </summary>
@ -179,7 +165,7 @@ namespace AsbCloudApp.Services
/// <param name="dotExtention"></param> /// <param name="dotExtention"></param>
/// <returns></returns> /// <returns></returns>
public string GetUrl(int idWell, int idCategory, int idFile, string dotExtention) => 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);
/// <summary> /// <summary>
/// пометить метку файла как удаленную /// пометить метку файла как удаленную
@ -207,7 +193,6 @@ namespace AsbCloudApp.Services
var ext = Path.GetExtension(entity.Name); var ext = Path.GetExtension(entity.Name);
var relativePath = GetUrl(entity.IdWell, entity.IdCategory, entity.Id, ext); var relativePath = GetUrl(entity.IdWell, entity.IdCategory, entity.Id, ext);
var fullPath = Path.GetFullPath(relativePath); var fullPath = Path.GetFullPath(relativePath);
fileStorageRepository.FileExists(fullPath, relativePath);
} }
return result; return result;
@ -327,7 +312,7 @@ namespace AsbCloudApp.Services
IdWell = idWell IdWell = idWell
}, },
token); 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; return result;
} }
@ -335,6 +320,7 @@ namespace AsbCloudApp.Services
/// Вывод списка всех файлов из базы, для которых нет файла на диске /// Вывод списка всех файлов из базы, для которых нет файла на диске
/// </summary> /// </summary>
/// <param name="idWell"></param> /// <param name="idWell"></param>
/// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
public async Task<IEnumerable<FileInfoDto>> GetListFilesNotDisc(int idWell, CancellationToken token) public async Task<IEnumerable<FileInfoDto>> GetListFilesNotDisc(int idWell, CancellationToken token)
{ {
@ -344,7 +330,7 @@ namespace AsbCloudApp.Services
IdWell = idWell IdWell = idWell
}, },
token); token);
var result = fileStorageRepository.GetListFilesNotDisc(idWell, files); var result = fileStorageRepository.GetListFilesNotDisc(files);
return result; return result;
} }
} }

View File

@ -14,31 +14,33 @@ namespace AsbCloudInfrastructure.Repository
#nullable enable #nullable enable
public class FileStorageRepository : IFileStorageRepository public class FileStorageRepository : IFileStorageRepository
{ {
public string RootPath { get; private set; } /// <summary>
/// Директория хранения файлов
/// </summary>
private readonly string RootPath = "files";
public FileStorageRepository() 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); CreateDirectory(filePathRec);
using var newfileStream = new FileStream(filePath, FileMode.Create); using var newfileStream = new FileStream(filePathRec, FileMode.Create);
await fileStream.CopyToAsync(newfileStream, token).ConfigureAwait(false); await fileStreamSrc.CopyToAsync(newfileStream, token).ConfigureAwait(false);
} }
public void DeleteFile(string fileName) public void DeleteFile(IEnumerable<string> filesName)
{
foreach (var fileName in filesName)
{ {
if (File.Exists(fileName)) if (File.Exists(fileName))
File.Delete(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); var sysFileInfo = new FileInfo(srcFilePath);
return sysFileInfo.Length; return sysFileInfo.Length;
} }
@ -49,52 +51,51 @@ namespace AsbCloudInfrastructure.Repository
File.Move(srcFilePath, filePath); 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) public string MakeFilePath(int idWell, int idCategory, string fileFullName, int fileId)
{ {
return Path.Combine(RootPath, $"{idWell}", return Path.Combine(RootPath, $"{idWell}",
$"{idCategory}", $"{fileId}" + $"{Path.GetExtension(fileFullName)}"); $"{idCategory}", $"{fileId}" + $"{Path.GetExtension(fileFullName)}");
} }
public int DeleteFilesNotExistStorage(int idWell, IEnumerable<int> idsFiles) public int DeleteFilesNotList(int idWell, IEnumerable<int> idsFilesList)
{ {
var allFilesPath = GetFilesPath(idWell); var allFilesPath = GetFilesPath(idWell);
var resutl = 0; var result = 0;
foreach (var filePath in allFilesPath) foreach (var filePath in allFilesPath)
{ {
var idFile = Path.GetFileNameWithoutExtension(filePath); if (int.TryParse(Path.GetFileNameWithoutExtension(filePath), out int idFile)
if (!idsFiles.Any(x => x.ToString() == idFile)) || !idsFilesList.Any(x => x == idFile))
{ {
File.Delete(filePath); File.Delete(filePath);
resutl++; result++;
} }
} }
return resutl; return result;
} }
public IEnumerable<FileInfoDto> GetListFilesNotDisc(int idWell, IEnumerable<FileInfoDto> files) public IEnumerable<FileInfoDto> GetListFilesNotDisc(IEnumerable<FileInfoDto> files)
{ {
var resutl = new List<FileInfoDto>(); var resutl = new List<FileInfoDto>();
var idsFilesStorage = GetIdsFiles(idWell); var groupFiles = files.GroupBy(x => x.IdWell);
foreach (var itemGroupFiles in groupFiles)
{
var idsFilesStorage = GetIdsFiles(itemGroupFiles.Key);
foreach (var file in files) foreach (var file in files)
{ {
if (!idsFilesStorage.Any(x => x == file.Id)) if (!idsFilesStorage.Any(x => x == file.Id))
resutl.Add(file); resutl.Add(file);
} }
}
return resutl; return resutl;
} }
public string GetUrl(int idWell, int idCategory, int idFile, string dotExtention) =>
Path.Combine(RootPath, idWell.ToString(), idCategory.ToString(), $"{idFile}{dotExtention}");
private IEnumerable<int> GetIdsFiles(int idWell) private IEnumerable<int> GetIdsFiles(int idWell)
{ {
var result = new List<int>(); var result = new List<int>();
@ -102,8 +103,8 @@ namespace AsbCloudInfrastructure.Repository
foreach (var filePath in allFilesPath) foreach (var filePath in allFilesPath)
{ {
var idFileStr = Path.GetFileNameWithoutExtension(filePath); int.TryParse(Path.GetFileNameWithoutExtension(filePath), out int idFile);
result.Add(Convert.ToInt32(idFileStr)); result.Add(idFile);
} }
return result; return result;

View File

@ -134,8 +134,6 @@ namespace AsbCloudWebApi.Tests.ServicesTests
var storageRepositoryMock = new Mock<IFileStorageRepository>(); var storageRepositoryMock = new Mock<IFileStorageRepository>();
storageRepositoryMock.Setup(x => x.RootPath).Returns("files");
fileService = new FileService(repositoryMock.Object, storageRepositoryMock.Object); fileService = new FileService(repositoryMock.Object, storageRepositoryMock.Object);
} }

View File

@ -7,6 +7,8 @@ using Microsoft.AspNetCore.Mvc;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Text;
using static System.Net.WebRequestMethods;
namespace AsbCloudWebApi.Controllers namespace AsbCloudWebApi.Controllers
{ {
@ -120,9 +122,10 @@ namespace AsbCloudWebApi.Controllers
try try
{ {
var fileInfo = await fileService.GetInfoAsync(fileId, token); var fileInfo = await fileService.GetInfoAsync(fileId, token);
var relativePath = fileService.GetUrl(fileInfo); 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) catch (FileNotFoundException ex)
{ {