【问题标题】:.NET WebClient.DownloadData get file type?.NET WebClient.DownloadData 获取文件类型?
【发布时间】:2014-08-02 08:46:03
【问题描述】:

为了处理从没有文件扩展名的 url 下载数据的情况, 我需要知道文件类型是什么。

例如,WebClient.DownloadData 方法如何显示它使用下面的 url 下载了 png [edit: jpeg] 图像?

https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcTw4P3HxyHR8wumE3lY3TOlGworijj2U2DawhY9wnmcPKnbmGHg

我在documentation 中没有找到任何描述如何执行此操作的内容。

【问题讨论】:

    标签: c# asp.net .net file webclient


    【解决方案1】:

    如果您信任标头信息,则可以使用WebClient 来做到这一点——您不需要使用HttpClient

    var webClient = new WebClient();
    var result = webClient.DownloadData(url);
    var contentType = webClient.ResponseHeaders["Content-Type"];
    
    if (contentType != null && 
        contentType.StartsWith("image", StringComparison.OrdinalIgnoreCase))
    {
        // it's probably an image
    }
    

    【讨论】:

      【解决方案2】:

      不能,直接。

      如果您信任 Web 服务器发回的标头,您可以使用不同的 HTTP 客户端(例如 WebRequestHttpClient)来使整个响应可用,而不仅仅是正文。然后您可以查看 Content-Type 标头。

      除此之外,您还需要查看内容本身。各种文件类型都有“幻数”,您可以使用它来识别文件 - 它们通常位于文件的开头,如果您只有一组有限的文件类型要查找,这可能是一种可行的方法.但它无法识别所有文件类型。

      例如,您链接到的图像的前四个字节是 ff d8 ff e0。这表明它实际上不是 jpeg 图像。碰巧,服务器响应包含content-type: image/jpeg的标头。

      【讨论】:

      • 感谢您的直截了当的回答。我编辑了我的问题,说明它是我忽略的 jpeg。
      【解决方案3】:

      您可以使用 HttpClient 来执行此 GET 请求。

      示例代码:

                  HttpClient client = new HttpClient();
                  var response = await client.GetAsync("https://encrypted-tbn2.gstatic.com/images?q=tbn%3aANd9GcTw4P3HxyHR8wumE3lY3TOlGworijj2U2DawhY9wnmcPKnbmGHg");
                  var filetype = response.Content.Headers.ContentType.MediaType;
                  var imageArray = await response.Content.ReadAsByteArrayAsync();
      

      在上述代码中,filetype 变量具有文件类型和扩展名为 image/JPEG 或 image/PNG 等。

      【讨论】:

      • 谢谢。这是我选择使用的答案。尽管由于其中包含的信息,我将 Jon's 标记为答案。
      【解决方案4】:

      您可以尝试使用FindMimeFromData API。这是sn-p。它可能会帮助你。

      WebClient webClient = new WebClient();
      var result = webClient.DownloadData(new Uri("url"));
      IntPtr mimeout;
      int result2 = FindMimeFromData(IntPtr.Zero, "sample", result, 4096, null, 0, out mimeout, 0);
      if (result2 != 0)
          throw Marshal.GetExceptionForHR(result2);
      string mime = Marshal.PtrToStringUni(mimeout);
      Marshal.FreeCoTaskMem(mimeout);
      Console.WriteLine(mime);
      

      这里是 API 声明。 (复制自here

      [DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]
      static extern int FindMimeFromData(IntPtr pBC, [MarshalAs(UnmanagedType.LPWStr)] string pwzUrl, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeParamIndex = 3)] 
      byte[] pBuffer, int cbSize, [MarshalAs(UnmanagedType.LPWStr)]  string pwzMimeProposed, int dwMimeFlags, out IntPtr ppwzMimeOut, int dwReserved);
      

      【讨论】:

      • ... 因此另一个依赖 Internet Explorer 的应用程序诞生了:D
      猜你喜欢
      • 2010-11-29
      • 2020-10-25
      • 1970-01-01
      • 2016-11-26
      • 1970-01-01
      • 2015-12-20
      • 2018-12-01
      • 2013-11-28
      • 1970-01-01
      相关资源
      最近更新 更多