AWS C# S3 SDK 使用MemoryStream替代FileStream时上传文件不完整问题
MemoryStream上传S3数据缺失问题排查及解决
你的代码存在3个核心问题,是导致数据截断的直接原因:
- XmlWriter缓冲区未刷新:你在
XmlDictionaryWriter的using块内部直接执行上传操作,此时writer内部的缓冲区还未刷新到MemoryStream中,末尾的XML闭合标签等内容还留在缓冲区里没有写入流,自然会缺失。你之前使用FileStream时,是等writer和FileStream的using块都结束之后才读取本地文件上传,此时已经自动触发了Flush操作,所以内容完整。 - 流读取位置未重置:就算提前刷新了缓冲区,写入操作完成后MemoryStream的当前位置
Position是在流的末尾,S3 SDK上传时会从当前位置往后读取内容,自然读不到前面写入的完整数据,需要手动把Position重置为0,从流的开头读取。 - 请求对象传参笔误:你创建了MemoryStream对应的上传请求对象
uploadRequest1,但调用Upload方法时传入的还是之前FileStream方案的uploadRequest,虽然这不是你本地写入MemoryStream也缺失的原因,但属于线上运行的显性bug。
修正后的代码
internal void WriteDataContractToFile(object data, string filename) { string path = @"C:\Jenova\restfulengine\RESTfulEngine\App_Data\requests\" + filename; try { // 原有FileStream方案逻辑可保留,此处省略 using (MemoryStream stream = new MemoryStream()) { using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8)) { DataContractSerializer dcs = new DataContractSerializer(data.GetType()); writer.WriteStartDocument(); dcs.WriteObject(writer, data); // 手动刷新缓冲区,将所有内容写入MemoryStream writer.Flush(); } // 重置流位置到开头,保证上传时读取全部内容 stream.Position = 0; var uploadRequest1 = new TransferUtilityUploadRequest(); uploadRequest1.InputStream = stream; uploadRequest1.Key = filename; uploadRequest1.BucketName = bucketName; // 传入正确的MemoryStream对应的请求对象 transferUtility.Upload(uploadRequest1); } } // 省略原有异常捕获逻辑 }
补充优化建议
如果需要避免XML头部出现UTF8 BOM字符,创建XmlDictionaryWriter时可以将编码参数替换为new UTF8Encoding(false)。
内容的提问来源于stack exchange,提问作者zaidabuhijleh
相关产品推荐
相关产品推荐

