RestSharp获取分块传输Zip归档:字符串是否为字节数组?如何重构保存?
问题与解决方案:使用RestSharp模拟下载Zip归档文件失败
问题描述
假设存在一个可下载压缩为Zip归档的XML文件的网站,该网站未提供任何API(包括RESTful API),需模拟用户点击下载按钮的行为,使用RestSharp编写了如下请求代码:
RestRequest postDownloadRequest = new RestRequest(Settings.DownloadUrl, Method.Post); postDownloadRequest.AddParameter("application/x-www-form-urlencoded", downloadBodyContent.ReadAsStringAsync().Result, ParameterType.RequestBody); Task<RestResponse> postDownloadResponseTask = client.ExecuteAsync(postDownloadRequest); postDownloadResponseTask.Wait();该代码请求返回200状态码,响应头Transfer-Encoding值为chunked,响应Content为长字符串,疑问此字符串是否为分块下载的归档文件字节数组转换而来?后续尝试将字符串转为byte[]再构建流,进而创建ZipArchive但失败,求正确的重构并本地保存Zip归档的方法。
核心问题分析
- 失败根源:直接读取
Content字符串会让二进制Zip数据被错误地以文本编码解析,破坏原始字节结构,转成byte[]后自然无法正常解压。 Transfer-Encoding: chunked是服务器的传输格式,RestSharp会自动处理分块拼接,无需手动操作,问题出在响应的读取方式上。
正确实现代码
直接用RestSharp的DownloadDataAsync获取原始字节数组,跳过文本解析步骤:
// 构建POST请求 var postDownloadRequest = new RestRequest(Settings.DownloadUrl, Method.Post); // 异步读取请求体,避免同步阻塞 postDownloadRequest.AddParameter("application/x-www-form-urlencoded", await downloadBodyContent.ReadAsStringAsync(), ParameterType.RequestBody); // 异步下载原始二进制数据 byte[] zipBytes = await client.DownloadDataAsync(postDownloadRequest); // 保存为本地Zip文件 File.WriteAllBytes("local_archive.zip", zipBytes); // 可选:验证Zip文件有效性 using (var stream = new MemoryStream(zipBytes)) { try { using (var archive = new ZipArchive(stream, ZipArchiveMode.Read)) { var firstEntry = archive.Entries.FirstOrDefault(); if (firstEntry != null) { Console.WriteLine($"Zip归档有效,包含条目:{firstEntry.Name}"); } } } catch (InvalidDataException ex) { Console.WriteLine("Zip归档无效:" + ex.Message); } }
关键优化点
- 替换同步阻塞:把
.Result和.Wait()换成await,避免死锁和性能损耗。 - 直接获取字节:用
DownloadDataAsync替代ExecuteAsync,直接拿到Zip归档的原始二进制数据,绕开文本编码干扰。 - 异步一致性:全程使用异步操作处理请求体和响应,保持代码逻辑的统一。
内容的提问来源于stack exchange,提问作者JCoppo
相关产品推荐
相关产品推荐

