我正在寻找一种简单的方法来获得mime类型,其中文件扩展名是不正确的或没有给出,类似于这个问题只有在. net。
当前回答
如果你想要托管你的ASP. mimetype,来自Nuget的guessmimetype将是最终的解决方案。NET解决方案在非windows环境。
文件扩展名映射非常不安全。如果攻击者上传无效的扩展名,映射字典将允许可执行文件在.jpg文件中分发。 因此,始终使用内容嗅探库来了解真正的内容类型。
public static string MimeTypeFrom(byte[] dataBytes, string fileName)
{
var contentType = HeyRed.Mime.MimeGuesser.GuessMimeType(dataBytes);
if (string.IsNullOrEmpty(contentType))
{
return HeyRed.Mime.MimeTypesMap.GetMimeType(fileName);
}
return contentType;
其他回答
如果你正在使用。net Framework 4.5或更高版本,现在有一个MimeMapping.GetMimeMapping(filename)方法,它将返回一个字符串,其中包含传递文件名的正确Mime映射。注意,这里使用的是文件扩展名,而不是文件本身中的数据。
文档请见http://msdn.microsoft.com/en-us/library/system.web.mimemapping.getmimemapping
我发现运行这段代码有几个问题:
UInt32 mimetype;
FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);
如果你尝试用x64/Win10运行它,你会得到
AccessViolationException "Attempted to read or write protected memory.
This is often an indication that other memory is corrupt"
多亏了这篇文章,PtrToStringUni在windows 10和@xanatos中无法工作
我修改了我的解决方案,在x64和。net Core 2.1下运行:
[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);
string getMimeFromFile(byte[] fileSource)
{
byte[] buffer = new byte[256];
using (Stream stream = new MemoryStream(fileSource))
{
if (stream.Length >= 256)
stream.Read(buffer, 0, 256);
else
stream.Read(buffer, 0, (int)stream.Length);
}
try
{
IntPtr mimeTypePtr;
FindMimeFromData(IntPtr.Zero, null, buffer, buffer.Length,
null, 0, out mimeTypePtr, 0);
string mime = Marshal.PtrToStringUni(mimeTypePtr);
Marshal.FreeCoTaskMem(mimeTypePtr);
return mime;
}
catch (Exception ex)
{
return "unknown/unknown";
}
}
谢谢
我最终使用了Netomatix的Winista MimeDetector。在您创建帐户http://www.netomatix.com/Products/DocumentManagement/MimeDetector.aspx后,可以免费下载这些源代码
MimeTypes g_MimeTypes = new MimeTypes("mime-types.xml");
sbyte [] fileData = null;
using (System.IO.FileStream srcFile = new System.IO.FileStream(strFile, System.IO.FileMode.Open))
{
byte [] data = new byte[srcFile.Length];
srcFile.Read(data, 0, (Int32)srcFile.Length);
fileData = Winista.Mime.SupportUtil.ToSByteArray(data);
}
MimeType oMimeType = g_MimeTypes.GetMimeType(fileData);
这是这里回答的另一个问题的一部分:在Urlmon.dll中FindMimeFromData方法的替代方法,它有更多的MIME类型 在我看来,这是解决这个问题的最好办法。
你好,我已经改编了Winista。MimeDetect项目到。net core/framework,回退到urlmon.dll,自由使用它:nuget包。
//init
var mimeTypes = new MimeTypes();
//usage by filepath
var mimeType1 = mimeTypes.GetMimeTypeFromFile(filePath);
您也可以查看注册表。
using System.IO;
using Microsoft.Win32;
string GetMimeType(FileInfo fileInfo)
{
string mimeType = "application/unknown";
RegistryKey regKey = Registry.ClassesRoot.OpenSubKey(
fileInfo.Extension.ToLower()
);
if(regKey != null)
{
object contentType = regKey.GetValue("Content Type");
if(contentType != null)
mimeType = contentType.ToString();
}
return mimeType;
}
无论如何,您都必须利用mime数据库——无论它们是从扩展还是魔术数字映射的,都有点微不足道——windows注册表就是这样一个地方。 对于独立于平台的解决方案,必须将此DB与代码一起发布(或作为独立的库)。
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 如何使用JSON确保字符串是有效的JSON。网
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?
- 如何分裂()一个分隔字符串到一个列表<字符串>
- 如何转换列表<字符串>列表<int>?
- c#对象列表,我如何得到一个属性的和