上传图片至S3 Bucket后文件损坏,请求协助排查修复
解决S3上传图片后无法打开的问题
你的代码存在三个核心问题,导致上传到S3的图片文件损坏:
1. 错误的流处理导致文件内容重复/无效
你先将文件内容读入fileBytes数组并写入MemoryStream,随后又调用file.CopyTo(stream),这会把原文件内容再次追加到流中,最终上传到S3的文件是原文件的两倍大小,直接导致文件损坏。同时,MemoryStream写入fileBytes后,流的位置停在末尾,直接上传会让S3读取空内容。
2. 错误设置ContentEncoding请求头
你在PutObjectRequest中添加了ContentEncoding = "base64",但实际上并没有对图片文件进行base64编码操作。这会让S3和下载端错误地尝试对二进制图片数据进行base64解码,导致文件内容错乱。
3. 文件读取不完整的风险
同步调用file.OpenReadStream().Read()时,该方法返回实际读取的字节数,无法保证一次性读完整个文件,可能导致部分内容丢失。
修正后的上传代码(推荐方案)
直接使用文件的原始流,避免不必要的字节数组转换和流复制:
private async Task<string> UploadFile(IFormFile file, string prefix, CancellationToken cancellationToken) { try { var fullPath = $"{prefix}/{file.FileName}"; using (var stream = file.OpenReadStream()) { var request = new PutObjectRequest { BucketName = _bucketName, Key = fullPath, InputStream = stream, Headers = { ContentDisposition = "attachment;" }, ContentType = file.ContentType }; await _client.PutObjectAsync(request, cancellationToken); } return fullPath; } catch (Exception e) { Console.WriteLine("UploadAttachmentFileAsync-exception" + e.StackTrace); throw new Exception($"{e.Message}: {Constants.MSG_FILE_STORAGE_ACCESS_FAILED}"); } }
备选方案(保留字节数组处理)
如果必须使用字节数组中转,需修正流位置并移除重复复制操作:
private async Task<string> UploadFile(IFormFile file, string prefix, CancellationToken cancellationToken) { try { byte[] fileBytes = new byte[file.Length]; int bytesRead = await file.OpenReadStream().ReadAsync(fileBytes, 0, (int)file.Length); if (bytesRead != file.Length) { throw new IOException("未能完整读取文件内容"); } var fullPath = $"{prefix}/{file.FileName}"; using (var stream = new MemoryStream(fileBytes)) { stream.Position = 0; // 重置流位置到开头 var request = new PutObjectRequest { BucketName = _bucketName, Key = fullPath, InputStream = stream, Headers = { ContentDisposition = "attachment;" }, ContentType = file.ContentType }; await _client.PutObjectAsync(request, cancellationToken); } return fullPath; } catch (Exception e) { Console.WriteLine("UploadAttachmentFileAsync-exception" + e.StackTrace); throw new Exception($"{e.Message}: {Constants.MSG_FILE_STORAGE_ACCESS_FAILED}"); } }
内容的提问来源于stack exchange,提问作者VIPIN PAL
相关产品推荐
相关产品推荐

