【发布时间】:2014-08-02 08:46:03
【问题描述】:
为了处理从没有文件扩展名的 url 下载数据的情况, 我需要知道文件类型是什么。
例如,WebClient.DownloadData 方法如何显示它使用下面的 url 下载了 png [edit: jpeg] 图像?
我在documentation 中没有找到任何描述如何执行此操作的内容。
【问题讨论】:
标签: c# asp.net .net file webclient
为了处理从没有文件扩展名的 url 下载数据的情况, 我需要知道文件类型是什么。
例如,WebClient.DownloadData 方法如何显示它使用下面的 url 下载了 png [edit: jpeg] 图像?
我在documentation 中没有找到任何描述如何执行此操作的内容。
【问题讨论】:
标签: c# asp.net .net file webclient
如果您信任标头信息,则可以使用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
}
【讨论】:
不能,直接。
如果您信任 Web 服务器发回的标头,您可以使用不同的 HTTP 客户端(例如 WebRequest 或 HttpClient)来使整个响应可用,而不仅仅是正文。然后您可以查看 Content-Type 标头。
除此之外,您还需要查看内容本身。各种文件类型都有“幻数”,您可以使用它来识别文件 - 它们通常位于文件的开头,如果您只有一组有限的文件类型要查找,这可能是一种可行的方法.但它无法识别所有文件类型。
例如,您链接到的图像的前四个字节是 ff d8 ff e0。这表明它实际上不是 jpeg 图像。碰巧,服务器响应也包含content-type: image/jpeg的标头。
【讨论】:
您可以使用 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 等。
【讨论】:
您可以尝试使用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);
【讨论】: