我正在开发一项下载大文件的服务。有一个 Web 前端,它发送一个 get 请求,该请求以流的形式接收文件。我已经研究过 Streamsaver.js,但我不想要中间人。目前使用方式是这样的
async function downloadFileFromStream(fileName, streamRef) {
// Get the stream from the .NET stream reference
const response = await streamRef.stream();
const readableStream = response.getReader();
const fileStream = streamSaver.createWriteStream(fileName);
if (window.WritableStream && readableStream.pipeTo) {
await readableStream.pipeTo(fileStream);
return;
}
const writer = fileStream.getWriter();
const pump = () => readableStream.read()
.then(({ done, value }) => {
if (done) {
writer.close();
return;
}
return writer.write(value).then(pump);
});
await pump();
}
// To register the function in the global window object so it can be called from C#
window.downloadFileFromStream = downloadFileFromStream;
我想知道是否有类似于我在 C# 中完成的方法
伪代码
Readstream r;
Writestream w;
r.copyToAsync(w);
javascript:
window.downloadFileFromStream = async function (fileName, streamRef) {
const response = await streamRef.stream();
const reader = response.getReader();
const writableStream = new WritableStream({
async write(chunk, controller) {
await writer.write(chunk);
},
close() {
writer.close();
}
});
const writer = writableStream.getWriter();
const pump = () => reader.read().then(({ done, value }) => {
if (done) {
writer.close();
return;
}
return writer.write(value).then(pump);
});
await pump();
}
包含这个js文件。
@page "/download"
@inject IJSRuntime JS
<button @onclick="DownloadFile">Download File</button>
@code {
private async Task DownloadFile()
{
var streamRef = new DotNetStreamReference(await GetFileStream());
await JS.InvokeVoidAsync("downloadFileFromStream", "example.txt", streamRef);
}
private async Task<Stream> GetFileStream()
{
var stream = new MemoryStream();
using (var writer = new StreamWriter(stream, leaveOpen: true))
{
await writer.WriteAsync("Example file content");
}
stream.Position = 0;
return stream;
}
}