C#如何实现可选择是否存储到本地磁盘的XML字符串上传到服务器
关于跳过Gzip转换的说明
完全可以跳过Gzip转换,是否需要解压仅取决于你请求的API返回的内容是否为gzip压缩格式:
- 如果接口返回的是未压缩的纯XML文本,直接删除GZipStream相关代码即可直接处理返回流
- 如果接口返回的是压缩内容,仅需要在内存中完成解压即可,不需要将文件落地到本地磁盘
直接使用MemoryStream实现「可选本地存储+上传到服务器」的方案
你现有的UploadFileStream(string file, Stream strm)方法天然支持直接从流上传,不需要先存本地磁盘,可按以下逻辑调整:
场景1:你拿到的是XML字符串(对应第一种代码写法)
// 1. 下载XML字符串 string xmlContent = _webClientService.DownloadXml("http://aws.api/Links?=admin"); // 2. 【可选:需要存本地时才执行这段】 string saveDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SampleFiles"); string savePath = Path.Combine(saveDir, "Sample.XML"); if (!Directory.Exists(saveDir)) { Directory.CreateDirectory(saveDir); } File.WriteAllText(savePath, xmlContent); // 3. 转MemoryStream直接上传 using var ms = new MemoryStream(Encoding.UTF8.GetBytes(xmlContent)); // 必须重置流位置到开头,否则上传的内容为空 ms.Position = 0; UploadFileStream("Sample.XML", ms);
场景2:你拿到的是接口返回的流(对应第二种代码写法)
如果返回内容不需要解压:
// 1. 获取接口返回流 Stream responseStream = await _httpService.GetStream("http://aws.api/Links?=admin"); // 2. 复制到可重复读取的MemoryStream using var ms = new MemoryStream(); await responseStream.CopyToAsync(ms); ms.Position = 0; // 3. 【可选:需要存本地时才执行这段】 string saveDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SampleFiles"); string savePath = Path.Combine(saveDir, "Sample.XML"); if (!Directory.Exists(saveDir)) { Directory.CreateDirectory(saveDir); } await using var fs = new FileStream(savePath, FileMode.Create, FileAccess.Write); ms.Position = 0; await ms.CopyToAsync(fs); // 4. 重置流位置后上传 ms.Position = 0; UploadFileStream("Sample.XML", ms);
如果返回内容需要gzip解压,仅需要在拿到返回流后增加一层解压逻辑即可,后续存本地/上传逻辑完全一致:
using var gzipStream = new GZipStream(responseStream, CompressionMode.Decompress); using var ms = new MemoryStream(); await gzipStream.CopyToAsync(ms); // 后续逻辑和上面完全一致
原代码优化建议
- 你现有的
GetStream方法存在阻塞风险,Task.Run+Wait的写法容易导致线程死锁,建议调整为纯异步实现:
public static async Task<Stream> GetStream(string url) { HttpResponseMessage response = await httpClient.GetAsync(url); switch (response.StatusCode) { case HttpStatusCode.OK: return await response.Content.ReadAsStreamAsync(); default: int statusCode = (int)response.StatusCode; throw new HttpException(statusCode, response.ReasonPhrase); } }
- 原代码中
XmlReader.Create(Xml)是错误用法,该重载接收的是XML文件路径/URI,如果要从字符串创建XmlReader,需要传入StringReader:XmlReader.Create(new StringReader(xmlContent)) - 路径拼接不要用字符串拼接,建议使用
Path.Combine()自动适配不同系统的路径分隔符,避免出错。
内容的提问来源于stack exchange,提问作者Walter
相关产品推荐
相关产品推荐

