-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to download a file larger than 500 MB #39
Comments
This method you mentioned above takes the entire stream as pass it to javascript entirely, and since your file is too big this error is expected. You need to use the overload method with the bufferSize to pass it by chunks to javascript. More bigger is the bufferSize then the download speed is better. |
Thanks for the answer, I'll try in 5 hours, I'll unsubscribe. |
I use this code, but it downloads a piece of buffer 1 time, then nothing happens. var fileInfo = new System.IO.FileInfo(filePath);
if (fileInfo.Exists)
{
var memory = new MemoryStream();
using FileStream fsSource = new(filePath, FileMode.Open, FileAccess.Read);
//fsSource.CopyTo(memory);
await downloadService.DownloadFile(file.FileName, fsSource , 32768, contentType: "application/octet-stream");
} |
Or here's another: using FileStream fsSource = new(filePath,FileMode.Open, FileAccess.Read);
await downloadService.DownloadFile(file.FileName, fsSource, 32768, contentType: "application/octet-stream", async (p) =>
{
Console.WriteLine(p);
await Task.Delay(0);
}); FileSize: Stream size: Console.WriteLine Output:
And download |
I user you code: await jsRuntime.InvokeVoidAsync("_blazorDownloadFileClearBuffer");
using FileStream fsSource = new(filePath,FileMode.Open, FileAccess.Read);
var totalOfBytes = (int)fsSource.Length;
var totalOfBytesReaded = 0;
var pendingBytesToRead = totalOfBytes;
do
{
var currentBufferSize = 32768 > totalOfBytes ? totalOfBytes : 32768 > pendingBytesToRead ? pendingBytesToRead : 32768;
var buffer = new byte[currentBufferSize];
totalOfBytesReaded += await fsSource.ReadAsync(buffer.AsMemory(0, currentBufferSize));
pendingBytesToRead -= totalOfBytesReaded;
await jsRuntime.InvokeVoidAsync("_blazorDownloadFileBuffersPush", buffer);
} while (pendingBytesToRead > 0);
var fileResult = await jsRuntime.InvokeAsync<DownloadFileResult>("_blazorDowloadFileByteArrayPartitioned", fileInfo.Name, "application/octet-stream");
Console.WriteLine(fileResult.ErrorName);
Console.WriteLine(fileResult.Succeeded); // True |
Where is this issue ocurring? Blazor server? Which browser and version? |
Also need to know which arq is your cpu and OS and how much memory you computer has since there are limitations when downloading big files through javascript per browser provider. |
Please read this and see if this case applies to your case. |
I did it like this. It works. await jsRuntime.InvokeVoidAsync("_blazorDownloadFileClearBuffer");
using FileStream fsSource = new(filePath, FileMode.Open, FileAccess.Read);
var buffer = new byte[2097152];
int bytesRead = await fsSource.ReadAsync(buffer);
await jsRuntime.InvokeVoidAsync("_blazorDownloadFileBuffersPush", buffer);
while (bytesRead > 0)
{
bytesRead = await fsSource.ReadAsync(buffer.AsMemory(0, 2097152));
await jsRuntime.InvokeVoidAsync("_blazorDownloadFileBuffersPush", buffer);
}
var fileResult = await jsRuntime.InvokeAsync<DownloadFileResult>("_blazorDowloadFileByteArrayPartitioned", fileInfo.Name, "application/octet-stream");
if (fileResult.Succeeded)
{
_notificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "Инфо", Detail = $"{file.FileName} отправлен на скачивание.", Duration = 4000 });
}
fsSource.Close();
await jsRuntime.InvokeVoidAsync("_blazorDownloadFileClearBuffer"); But there is a nuance, when the user clicked on the download button, he first downloads the buffer, and only then the save appears. |
Latest Yandex, Opera. Blazor Server |
In js, can it be first to give the user a link, and then write bytes there? |
This is the way it works, and there is nothing else we can do about it. You may need to increase the buffer size as you seems to do it already to lower the requests number. Remember that blazor is transferring the bytes in chunks from blazor server to javascript via js interop. |
what you mean by this? |
The trick over here is increase the buffer size. Blazor server signal r should be halting from so many request on so short time span. Increase the buffersize to 2-5 megabytes and try again for that download. |
In ASP net core, they used to do this: https://stackoverflow.com/questions/42460198/return-file-in-asp-net-core-web-api In the Blazor, you can give a link to the file https://docs.microsoft.com/en-us/aspnet/core/blazor/file-downloads ?view=aspnetcore-6.0 |
I'll try it tomorrow, but I think I can find an alternative. And do , for example , how to give files to Google Dock . Generate a link, the user receives a link to the stream, the browser understands and downloads. |
And yes, even if I recommend use content-disposition from files incoming from the server, you can still download files from the server as you are trying to do over my library but huge files incoming from the server as is your case will halt blazor server or javascript max blob size on the browser side if it's extremely big or you dont tune up the buffersize. |
Please let me know if this worked for you so I may start migration. |
Unable to download a file larger than 500 MB.
Used your library, in particular the method: DownloadFile(string filename, Stream stream, CancellationToken cancellationTokenBytesRead, CancellationToken cancellationTokenJavaScriptInterop, string ContentType = "application/octet-stream").
But when you try to download a file larger than 200 MB, an exception occurs, which says that there was not enough memory.
Stream was too long
Question on Stackoverflow: https://stackoverflow.com/questions/72356882/generate-a-link-to-the-download-file
The text was updated successfully, but these errors were encountered: