【发布时间】:2023-03-15 03:02:01
【问题描述】:
我正在尝试找出将大文件上传到服务器的最佳方式。在我的本地,我尝试了两种方法:
- 顺序分块上传,其中文件被分解为多个块并一次上传一个到服务器。在服务器端,传入的块直接附加到最终文件中。
- 并行块上传,其中块并行上传到服务器。服务端将文件存储为临时小文件,等所有chunk上传完成后合并为一个完整的文件。
但是与上传时间相比,这里的合并时间要长得多,至少在我的本地。因此,并行上传总是比顺序上传慢很多。如何缩短上传时间?
这是顺序上传代码:
[HttpPost]
[RequestFormLimits(MultipartBodyLengthLimit = 209715200)]
[RequestSizeLimit(209715200)]
public async Task<IActionResult> UploadSeq()
{
string filename = "./Uploads/seqfile";
using(Stream file = Request.Body)
using (FileStream stream = new FileStream(filename, FileMode.Append))
{
await file.CopyToAsync(stream);
await stream.FlushAsync();
}
return Ok();
}
这是并行代码:
[HttpPost("/ParUpload/{id}/{size}")]
[RequestFormLimits(MultipartBodyLengthLimit = 209715200)]
[RequestSizeLimit(209715200)]
public async Task<IActionResult> UploadParallel(int id, int size)
{
string filename = "./Uploads/parfilecomplete.mkv";
using (Stream file = Request.Body)
using (FileStream stream = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write))
{
stream.Seek(id * size, SeekOrigin.Begin);
await file.CopyToAsync(stream);
await stream.FlushAsync();
}
return Ok();
}
【问题讨论】:
-
是的,你可以。 Torrent 协议就像一个快速的例子。直接将块写入目标文件中的位置。限制导致重用套接字的并发上传数量,这将避免建立大量新的 TCP 连接。
-
我也尝试过这种方法,但仍然比顺序方法慢很多..
-
请在两边显示两个实现的代码。不能再慢了。
-
取决于硬件(真实磁盘与 SSD 的寻道成本不一样)。还尝试删除刷新调用。 Windows 也有 WriteFileGather 但没有暴露给 .NET。 docs.microsoft.com/en-us/windows/win32/api/fileapi/… 不确定它会添加什么。您应该发布重现的服务器和客户端测试代码。魔鬼藏在细节里。
标签: c# .net asp.net-mvc file