代码之家  ›  专栏  ›  技术社区  ›  dkarzon Sven Grosen

C保存来自HTTP请求的文件

c#
  •  20
  • dkarzon Sven Grosen  · 技术社区  · 16 年前

    我试图从httpwebresponse下载并保存文件,但在正确保存文件(文本文件除外)时遇到问题。

    我认为这与这部分有关:

    byte[] byteArray = Encoding.UTF8.GetBytes(http.Response.Content);
    MemoryStream stream = new MemoryStream(byteArray);
    

    使用上面的代码,文本文件可以正常工作,但是当我尝试将内容保存到图像文件时,它会损坏。 如何将此“字符串”数据写入图像文件(和其他二进制文件)

    忘了提一下,这是.net cp 3.5,我在httpWebResponse类周围有一个包装类来添加OAuth等。

    3 回复  |  直到 8 年前
        1
  •  48
  •   johnny 5    8 年前

    问题是,你将二进制数据解释为文本,即使它不是文本——一旦你开始将内容视为字符串而不是字节,你就有麻烦了。您尚未提供包装类的详细信息,但我假设 Content 属性正在返回字符串-您将无法使用该字符串。如果包装器类不允许从Web响应获取原始数据,则需要修改它。

    如果使用.NET 4,则可以使用新的CopyTo方法:

    using (Stream output = File.OpenWrite("file.dat"))
    using (Stream input = http.Response.GetResponseStream())
    {
        input.CopyTo(output);
    }
    

    如果不使用.NET 4,则必须手动进行复制:

    using (Stream output = File.OpenWrite("file.dat"))
    using (Stream input = http.Response.GetResponseStream())
    {
        byte[] buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            output.Write(buffer, 0, bytesRead);
        }
    }
    
        2
  •  7
  •   Matthew Flaschen    16 年前

    使用 WebClient.DownloadFile . 你可以手动操作 like this ,但是WebClient是简单下载的最佳选择。

        3
  •  0
  •   johnny 5    8 年前

    我发现最简单的方法是:

    • 使用readasbytearrayasync获取数据。
    • 列表项 file.writeallbytes保存文件。

    不需要循环任何东西。以下上下文中的示例:

    [TestClass]
    public class HttpTests
    {
        [TestMethod]
        public void TestMethod1()
        {
            var jsObject = (dynamic)new JObject();
            jsObject.html =  "samplehtml.html";
            jsObject.format = "jpeg";
            const string url = "https://mywebservice.com/api";
    
            var result =   GetResponse(url, jsObject).GetAwaiter().GetResult();
            File.WriteAllBytes($@"c:\temp\httpresult.{jsObject.format}", result);
        }
    
        static async Task<byte[]> GetResponse(string uri, dynamic jsObj)
        {
            var httpClient = new HttpClient();
            var load = jsObj.ToString();
            var content = new StringContent(load, Encoding.UTF8, "application/json");
            var response = await httpClient.PostAsync(uri, content);
            return await response.Content.ReadAsByteArrayAsync();
        }
    }