DotNet 8 Blazor Server大文件上传保存后损坏/不完整问题求助
问题原因分析
你的代码核心问题在于假设ReadAsync会一次性读取完整的文件内容,但实际上对于较大的文件(比如1MB左右),流的读取操作可能需要多次执行才能完成全部数据的读取,直接用一次ReadAsync会导致部分字节未被读取,最终保存的文件不完整或字节错乱。
另外,代码中手动调用Dispose的方式不够严谨,容易因遗漏或异常导致资源泄漏。
修复后的代码示例
@page "/counter" <InputFile multiple OnChange="OnChange" class="form-control"></InputFile> @code { private async Task OnChange(InputFileChangeEventArgs e) { // 确保目标目录存在 var targetDir = @"C:\test"; if (!Directory.Exists(targetDir)) { Directory.CreateDirectory(targetDir); } foreach (var item in e.GetMultipleFiles()) { // 使用using自动释放流资源 using var readStream = item.OpenReadStream(item.Size); // 生成唯一文件名,避免多文件上传时覆盖 var targetPath = Path.Combine(targetDir, $"{Guid.NewGuid()}_{item.Name}"); using var writeStream = File.Create(targetPath); // 用缓冲区循环读取并写入,确保所有字节都被处理 var buffer = new byte[8192]; int bytesRead; while ((bytesRead = await readStream.ReadAsync(buffer)) > 0) { await writeStream.WriteAsync(buffer.AsMemory(0, bytesRead)); } } } }
关键修复点说明
- 循环读取流:用
while循环持续调用ReadAsync,直到返回的字节数为0,确保所有文件数据都被读取。 - 使用
using语句:自动管理readStream和writeStream的生命周期,无需手动调用Dispose,using块结束时会自动完成资源释放和缓冲区刷新。 - 避免文件名冲突:通过
Guid.NewGuid()生成唯一前缀,防止多文件上传时覆盖同名文件。 - 检查目标目录:提前创建目标目录,避免因目录不存在导致的保存失败。
内容的提问来源于stack exchange,提问作者dzz
相关产品推荐
相关产品推荐

