Dot-Net
如何確定文件是否為 .NET 中的圖像文件?
我不想依賴文件副檔名。我不關心它是什麼類型的圖像(.jpg、.png 等),我只是想知道文件是否是圖像。如果可能,我寧願不使用任何非 .NET dll。
我知道如何做到這一點的最佳方法如下:
bool isImageFile; try { Image.FromFile(imageFile).Dispose(); isImageFile = true; } catch (OutOfMemoryException) { isImageFile = false; }如此處所述:http: //msdn.microsoft.com/en-us/library/stf701f5.aspx,如果文件不是有效的圖像格式,則
Image.FromFile()拋出一個。OutOfMemoryException使用上面給出的結果正是我想要的,但我不希望使用它,原因如下:
- 我認為,出於性能原因,將 try-catch 用於正常程序執行是一種不好的做法。
Image.FromFile()將整個圖像文件(如果是圖像文件)載入到記憶體中。我認為這很浪費,因為我只需要文件類型,此時不需要在我的程式碼中進行任何進一步的圖像處理。- 我不喜歡擷取
OutOfMemoryExceptions 因為如果有一個真正的記憶體不足問題並且我的程序吞下它並繼續執行怎麼辦?**有沒有更好的方法來做到這一點?**或者,我上面列出的任何/所有問題都是沒有根據的嗎?
編輯:由於在這裡收到答案,這些是我現在知道的三個解決方案:
Image.FromFile()通過和 try-catch 將整個圖像載入到記憶體中。
- 優點:對圖像文件內容進行更深入的檢查;涵蓋許多圖像類型。
- 缺點:最慢;try-catch 和將完整圖像文件載入到記憶體中的成本;擷取“真正的”OutOfMemoryException 的潛在危險。
- 檢查圖像文件的標頭字節。
- 優點:快速,低記憶體使用。
- 缺點:可能很脆弱;需要為每種文件類型程式。
- 檢查文件副檔名。
- 優點:最快;最簡單的。
- 缺點:並非在所有情況下都有效;最容易出錯。
(我沒有看到明確的“贏家”,因為我可以想像每個人都適合的情況。出於我的應用程序的目的,文件類型檢查很少發生,以至於方法 1 的性能問題不是問題。)
- 如果您不斷拋出異常,您只會注意到異常對性能的影響。因此,除非您的程序希望看到許多無效圖像(每秒數百個),否則您不應該注意到異常處理的成本。
- 這確實是判斷圖像是完整圖像還是損壞的唯一方法。您可以按照其他人的建議檢查標頭,但這僅檢查開頭的幾個字節是否正確,其他任何內容都可能是垃圾。這是否足夠好取決於您的應用程序的要求。只需閱讀標題可能就足以滿足您的案例。
- 是的,這對 BCL 團隊來說是相當糟糕的設計。如果您正在載入許多大圖像,那麼您很可能會在大對象堆中遇到真正的 OOM 情況。據我所知,沒有辦法區分這兩個例外。
如果您只支持少數流行的圖像格式,那麼您可以簡單地讀取文件的前幾個字節來確定基於幻數的類型
提供的連結中的範例:
- GIF 圖像文件的 ASCII 程式碼為“GIF89a”(47 49 46 38 39 61)或“GIF87a”(47 49 46 38 37 61)
- JPEG 圖像文件以 FF D8 開頭,以 FF D9 結尾。JPEG/JFIF 文件包含“JFIF” (4A 46 49 46) 的 ASCII 程式碼作為空終止字元串。
- PNG 圖像文件以 8 字節簽名開始,該簽名將文件標識為 PNG 文件並允許檢測常見的文件傳輸問題:\211 PNG \r \n \032 \n (89 50 4E 47 0D 0A 1A 0A)。