forked from ddrilling/AsbCloudServer
#6385536 Замечания
This commit is contained in:
parent
0b2ae0b361
commit
b54de8fe06
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user