Created download systems, for files.
This commit is contained in:
parent
f468af89e0
commit
f311e14ec1
|
|
@ -114,4 +114,14 @@ public class FilesController(
|
|||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
public async Task<IActionResult> Download(Guid id)
|
||||
{
|
||||
|
||||
var filename = await fileRepository.GetFileName(id);
|
||||
|
||||
var stream = fileRepository.EnumerateFileContentsAsync(id);
|
||||
|
||||
return File(stream, "application/octet-stream", filename);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
using System.Security.Cryptography.X509Certificates;
|
||||
using FileStorageService.www.Data;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
|
@ -8,7 +9,7 @@ public class FileRepository(ApplicationDbContext context)
|
|||
{
|
||||
public static readonly int MAX_BLOCKS = 10_485_760;
|
||||
|
||||
private readonly Queue<(string, Stream)> _creationQueue = new();
|
||||
private readonly Queue<(string, Stream, TaskCompletionSource<Guid?>)> _creationQueue = new();
|
||||
private readonly Lock _countLock = new();
|
||||
|
||||
public async Task<List<FileHandle>> GetAllFilesAsync()
|
||||
|
|
@ -23,60 +24,89 @@ public class FileRepository(ApplicationDbContext context)
|
|||
.Include(e => e.FileBlocks).FirstAsync();
|
||||
}
|
||||
|
||||
public Task<string> GetFileName(Guid id)
|
||||
{
|
||||
return (from handle in context.FileHandles
|
||||
where handle.Id == id
|
||||
select handle.Name).FirstAsync();
|
||||
}
|
||||
|
||||
public Stream EnumerateFileContentsAsync(Guid id)
|
||||
{
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
var writer = new BinaryWriter(memoryStream);
|
||||
|
||||
var query = (from block in context.FileBlocks
|
||||
where block.FileHandle.Id == id
|
||||
orderby block.BlockNumber
|
||||
select block.Data);
|
||||
|
||||
foreach (var bytes in query.AsEnumerable())
|
||||
{
|
||||
writer.Write(bytes);
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
memoryStream.Position = 0;
|
||||
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
public Task<Guid?> TryNewFileAsync(string name, Stream reader)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<Guid?>();
|
||||
|
||||
lock (_creationQueue)
|
||||
{
|
||||
_creationQueue.Enqueue((name, reader));
|
||||
_creationQueue.Enqueue((name, reader, tcs));
|
||||
}
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
|
||||
Stream stream;
|
||||
string name;
|
||||
|
||||
lock (_creationQueue)
|
||||
{
|
||||
(name, stream) = _creationQueue.Dequeue();
|
||||
}
|
||||
|
||||
var fileHandle = new FileHandle
|
||||
{
|
||||
Name = name
|
||||
};
|
||||
|
||||
var handle = await CreateFileBlocks(stream, fileHandle);
|
||||
var currentFileCount = handle.FileBlocks.Count();
|
||||
handle.FileBlockCount = currentFileCount;
|
||||
|
||||
lock (_countLock)
|
||||
{
|
||||
var count = context.FileBlocks.Count();
|
||||
|
||||
if (count+currentFileCount > MAX_BLOCKS)
|
||||
{
|
||||
tcs.SetResult(null);
|
||||
return;
|
||||
}
|
||||
|
||||
context.Add(fileHandle);
|
||||
context.SaveChangesAsync();
|
||||
|
||||
tcs.SetResult(fileHandle.Id);
|
||||
}
|
||||
});
|
||||
Task.Run(async () => await StartProcessFileUpload());
|
||||
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
private async Task StartProcessFileUpload()
|
||||
{
|
||||
Stream stream;
|
||||
string name;
|
||||
TaskCompletionSource<Guid?> tcs;
|
||||
|
||||
lock (_creationQueue)
|
||||
{
|
||||
(name, stream, tcs) = _creationQueue.Dequeue();
|
||||
}
|
||||
|
||||
var fileHandle = new FileHandle
|
||||
{
|
||||
Name = name
|
||||
};
|
||||
|
||||
var handle = await CreateFileBlocks(stream, fileHandle);
|
||||
var currentFileCount = handle.FileBlocks.Count();
|
||||
handle.FileBlockCount = currentFileCount;
|
||||
|
||||
lock (_countLock)
|
||||
{
|
||||
var count = context.FileBlocks.Count();
|
||||
|
||||
if (count+currentFileCount > MAX_BLOCKS)
|
||||
{
|
||||
tcs.SetResult(null);
|
||||
return;
|
||||
}
|
||||
|
||||
context.Add(fileHandle);
|
||||
context.SaveChangesAsync();
|
||||
|
||||
tcs.SetResult(fileHandle.Id);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<FileHandle> CreateFileBlocks(Stream reader, FileHandle fileHandle)
|
||||
{
|
||||
var blockNumber = 0;
|
||||
var blocks = new List<FileBlock>();
|
||||
var buffer = new byte[1024];
|
||||
|
||||
while (await reader.ReadAsync(buffer) > 0)
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@
|
|||
<a
|
||||
asp-controller="Files" asp-action="Index" asp-route-id="@file.Id"
|
||||
class="btn btn-primary me-2">View...</a>
|
||||
<a
|
||||
asp-controller="Files" asp-action="Download" asp-route-id="@file.Id"
|
||||
class="btn btn-success me-2">Download</a>
|
||||
<a
|
||||
asp-controller="Files" asp-action="ConfirmDelete" asp-route-id="@file.Id"
|
||||
class="btn btn-danger">Delete...</a>
|
||||
|
|
|
|||
Loading…
Reference in New Issue