【发布时间】:2021-06-04 22:24:27
【问题描述】:
我有一个 C# 中的 Web 表单应用程序,我必须根据其输入流检查文件类型是否为视频。
我尝试了几种方法,包括以下。
protected void btnUpload_Click(object sender, EventArgs e)
{
if (FileUpload1.PostedFile != null)
{
try
{
string FileName = Path.GetFileName(FileUpload1.PostedFile.FileName);
if (FileUpload1.PostedFile.InputStream.Length <= 0)
txt_response.Text = "Invalid file.";
byte[] buffer = new byte[256];
Stream fs = FileUpload1.PostedFile.InputStream;
BinaryReader br = new BinaryReader(fs);
if (fs.Length >= 256)
fs.Read(buffer, 0, 256);
else
fs.Read(buffer, 0, (int)fs.Length);
System.UInt32 mimetype;
FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);
System.IntPtr mimeTypePtr = new IntPtr(mimetype);
string mime = Marshal.PtrToStringUni(mimeTypePtr);
Marshal.FreeCoTaskMem(mimeTypePtr);
//mime of video file remains application/octet-stream
}
catch (Exception ex)
{
throw ex;
}
}
}
[DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
private extern static System.UInt32 FindMimeFromData(System.UInt32 pBC, [MarshalAs(UnmanagedType.LPStr)] System.String pwzUrl, [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer, System.UInt32 cbSize,
[MarshalAs(UnmanagedType.LPStr)] System.String pwzMimeProposed, System.UInt32 dwMimeFlags, out System.UInt32 ppwzMimeOut, System.UInt32 dwReserverd);
}
上面的代码适用于大多数文件类型,但对于视频,它返回 application/octate-stream,尽管视频是 mp4。
我们有没有办法检查该缓冲区并确定它是视频文件还是图像文件等?
任何帮助将不胜感激。谢谢!
【问题讨论】:
-
@Jimi 谢谢,关于如何从 InputStream 的签名或幻数中获取此信息的任何想法?
-
如果您使用 MimeGuesser 工具,它有重载,您可以向其传递字节数组或 Stream 对象。如果您自己这样做(例如,使用
Dictionary<MimeType, byte[]>),这与您现在正在做的事情相同:不是读取 256 个字节,而是读取字典的每个Value.Length。请注意,mp4格式(与其他类似媒体一样)是一个容器,因此它可能包含不同的子格式,但也许您对子格式不感兴趣,只对容器类型感兴趣. -
您还可以获取这 256 个字节(这比任何签名所需的要多得多),然后 - 假设来自
Dictionary<MimeType, byte[]>的值是var mimeBytes = new byte[] { FF, D8, FF, E0 };(基本 JPEG/JFIF) - 你可以然后将序列比较为var isEqual = streamBytes.Take(mimeBytes.Length).SequenceEqual(mimeBytes);。当然循环 KeyValuePairs 或您的字典。如果/当一个值匹配时,取那个索引处的字典键。
标签: c# file-upload mime-types content-type