回答
不確定,但也許你應該調查約magic numbers。
更新: 讀了一下,我不認爲它是非常可靠的。
您不能從字節流知道,但你可以存儲MIME類型,當你開始填充byte[]
。
一般,你不能。但是,您可以使用啓發式檢查幻數並以很好的概率猜測內容類型(如UNIX中的'file'命令)。你可以檢查它的來源。 – 2009-10-31 16:35:29
Randolph,我該怎麼做? – AndreMiranda 2009-10-31 16:36:23
你可以用System.Net.Mail的ContentType來僞造它,通過將你上傳的文件轉換成附件(不難做到),或者你可以從這個問題嘗試URLMON.DLL破解:http://stackoverflow.com/questions/58510/in-c-how-can-you-find-the-mime-type-of-the-file-based-on-the-file-signature-not-th – 2009-10-31 22:50:34
簡短的回答:你不能
較長的答案:通常情況下,程序使用的文件擴展名來知道他們正在處理的是什麼類型的文件。如果您沒有該擴展名,則只能進行猜測......例如,您可以查看前幾個字節,並檢查是否識別了一個衆所周知的標頭(例如XML聲明標籤,或位圖或JPEG標頭)。但是這將永遠是一個猜測:如果沒有一些元數據或內容信息,字節數組毫無意義...
一個很好的例子可能是所有的文件類型包裹zip/cab文件(即.docx)。據推測,如果我能夠簡單地更改擴展名並用另一個程序打開文件,那麼底層文件字節的「幻數」將是相同的,因此導致含糊不清。 – JoeBrockhaus 2014-12-03 21:49:49
你不想這樣做。當文件上傳時調用Path.GetExtension,並將擴展名與byte []一起傳遞。
我該怎麼做? – AndreMiranda 2009-10-31 16:35:28
如何驗證擴展名是文件本身的內容?即。以JPG格式存儲的PDF – user3308043 2014-07-24 22:52:31
讓我想起那天我們回來的,呃嗯用來分享早期的免費圖片託管網站上50MB的RAR文件,只需添加.gif擴展名的文件名.rar程序「一些人」。
顯然,如果你是面向公衆的,你的期待某個文件類型,你必須確保它是文件類型,那麼你就不能只信任該擴展程序。另一方面,如果您的應用程序沒有理由不信任上傳的擴展名或MIME類型,那麼只需在上傳文件時像從@rossfabircant和@RandolphPotter收到的答案那樣獲取這些文件。創建一個具有byte []的類型,以及原始擴展名或mimetype,並傳遞該類型。
如果您需要驗證該文件實際上是有一定預期的類型像一個有效的.jpeg或.png你可以嘗試解釋文件爲這些類型,看看它是否成功打開。 (System.Drawing.Imaging.ImageFormat)
如果您試圖僅從二進制內容對文件進行分類,並且它可能是整個世界中的任何格式,那真是一個艱難的開放式問題,而且沒有100%可靠的方法來做到這一點。你可以針對它調用TrID,如果你能找到(並負擔得起),那麼執法調查人員可能會使用類似的取證工具。
如果你不必這麼做,那就不要這麼做。
邊緣情況的好答案。 – user3308043 2014-07-24 22:53:21
如前所述,MIME魔術是實現此目的的唯一方法。許多平臺都提供最新且強大的MIME魔術文件和代碼,以便高效地完成此操作。在沒有任何第三方代碼的情況下在.NET中執行此操作的唯一方法是使用urlmon.dll中的。方法如下:
public static int MimeSampleSize = 256;
public static string DefaultMimeType = "application/octet-stream";
[DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
private extern static uint FindMimeFromData(
uint pBC,
[MarshalAs(UnmanagedType.LPStr)] string pwzUrl,
[MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
uint cbSize,
[MarshalAs(UnmanagedType.LPStr)] string pwzMimeProposed,
uint dwMimeFlags,
out uint ppwzMimeOut,
uint dwReserverd
);
public static string GetMimeFromBytes(byte[] data) {
try {
uint mimeType;
FindMimeFromData(0, null, data, (uint)MimeSampleSize, null, 0, out mimeType, 0);
var mimePointer = new IntPtr(mimeType);
var mime = Marshal.PtrToStringUni(mimePointer);
Marshal.FreeCoTaskMem(mimePointer);
return mime ?? DefaultMimeType;
}
catch {
return DefaultMimeType;
}
}
這使用Internet Explorer MIME檢測器。這是IE用來發送MIME類型和上傳文件的相同代碼。你可以看到list of MIME types supported by urlmon.dll。有一點需要注意的是非標準的image/pjpeg
和image/x-png
。在我的代碼中,我將它們替換爲image/jpeg
和image/png
。
你extern方法聲明好像是錯的。有人在此處撰寫了這篇文章:http://webandlife.blogspot.com/2012/11/google-is-your-alcoholic-friend.html – SandRock 2013-07-21 22:56:15
有趣的是,他在重構之前的代碼與重構之後的代碼完全相同。對於指出別人錯誤的人來說,這並不好,但顯然不能自己處理複製/粘貼。有點辜負他的信譽不是嗎? :) – Mrchief 2014-08-01 14:59:27
@Mrlflf:這是不一樣的。我發現的第一個區別是將'uint'更改爲'IntPtr'。這是有道理的,因爲這篇文章是專門討論匹配C和C#數據類型的主題。 – 2017-12-08 19:26:22
如果您想要支持的預期文件類型數量有限,可以使用幻數。
一個簡單的檢查方法是使用文本/十六進制編輯器打開示例文件,並研究前導字節以查看是否有可用於區分/丟棄支持集中的文件的文件。
另一方面,如果您希望識別任何任意文件類型,是的,正如大家已經說過的那樣,強硬。
使用System.Drawing.Image'RawFormat.Guid'屬性可以檢測MIME類型的圖像。
但我不知道如何找到其他文件類型。
http://www.java2s.com/Code/CSharp/Network/GetImageMimeType.htm
UPDATE:,你可以嘗試考慮看看這個帖子上
Using .NET, how can you find the mime type of a file based on the file signature not the extension
如果你知道這是一個System.Drawing.Image
,你可以這樣做:
public static string GeMimeTypeFromImageByteArray(byte[] byteArray)
{
using (MemoryStream stream = new MemoryStream(byteArray))
using (Image image = Image.FromStream(stream))
{
return ImageCodecInfo.GetImageEncoders().First(codec => codec.FormatID == image.RawFormat.Guid).MimeType;
}
}
- 1. 如何從http響應中知道文件類型和名稱?
- 2. 如何知道文件類型?
- 3. 在Java或Groovy中,如何找到byte []的文件類型?
- 4. C如何知道期望的類型?
- 5. 從owin中間件,如何知道控制器名稱/類型?
- 6. 如何知道C中未知類型變量的數據類型?
- 7. 如何知道xcode中的類型文件
- 8. 如何知道NSManagedContext中NSManagedObject的類型
- 9. 如何在C++中聲明byte *(byte array)?
- 10. 如何從Openstack中的Image中知道OS類型?
- 11. 如何在C#中將值類型轉換爲byte []?
- 12. 如何在C頭中定義BYTE類型的變量?
- 13. 如何在C#中將'system.windows.media.imagesource'類型轉換爲'system.drawing.image'或byte []?
- 14. 如何知道C#.NET中的URL的內容類型?
- 15. 如何知道Iphone上Objective C中變量的類型?
- 16. 在C++中知道子類的類
- 17. 在VS C++中從BYTE *到int *的類型轉換
- 18. C#如何知道文字是什麼類型?
- 19. 如何從使用P/Invoke中知道要編組的類型?
- 20. 如何在codeigniter中上傳文件時準確知道錯誤類型?
- 21. 如何知道在jsp中有多少個對象類型=「文件」
- 22. 如何匹配byte []類型?
- 23. 如何在C#創建類型從XML文件中的DataTable
- 24. 如何將C中的數據類型byte []轉換爲delphi?
- 25. 哪個C/C++頭文件定義了BYTE數據類型?
- 26. 在Java中:如何從byte []數組中壓縮文件?
- 27. 如何知道一個類型是否已經在C#中的另一個源文件中聲明?
- 28. 如何以編程方式知道文件類型?
- 29. 如何知道文件的類型,保存,使用QFileDialog
- 30. 如何使用Boost.Filesystem知道文件的類型?
「FindMimeData」甚至沒有檢測到像audio/mp3這樣基本的內容,所以如果您在26種以外的地方檢測到某些東西,幻數是唯一的選擇。你能否詳細說明爲什麼你認爲它不可靠? – Mrchief 2014-08-01 15:28:13