Java如何判断一个上传文件的内容类型
關于如何判斷一個文件的類型,在如何判斷一個文件的類型_jimmyleeee的博客-CSDN博客已經介紹了,但是在實際運用于真正的文件上傳時,還是有些注意事項需要注意的。
在進入主題之前,首先需要簡單介紹一下MultipartFile這個類,通過getOriginalFilename()獲取文件的名字,但是這個名字只是上傳文件的名字,通過這個名字是無法訪問到這個文件的。以下是測試時的debug信息:
可以看到?MultipartFile類中,有filename,有filelocation,甚至還有臨時文件的絕對路勁和名字,但是,卻沒有接口可以獲取這些信息。也就是說,通過類MultipartFile只能獲得文件名和文件流。
再說,使用Files.probeContentType檢測上傳的MultipartFile時,為什么可以正常工作。在Files.probeContentType中設置一個斷點,可以發現進入函數之后,會直接調轉到1624行,調用
FileTypeDetectors.defaultFileTypeDetector的probeContentType?通過進一步定義跟蹤,默認的defaultFileTypeDetector是RegistryFileTypeDetector,根據基類AbstractFileTypeDetector中probeContentType的實現如下:
public final String probeContentType(Path var1) throws IOException {if (var1 == null) {throw new NullPointerException("'file' is null");} else {String var2 = this.implProbeContentType(var1);if (var2 == null) {Path var3 = var1.getFileName();if (var3 != null) {FileNameMap var4 = URLConnection.getFileNameMap();var2 = var4.getContentTypeFor(var3.toString());}}return var2 == null ? null : parse(var2);}}其中,主要是implProbeContentType中實現對內容類型的分析。回到RegistryFileTypeDetector的implProbeContentType函數:
public String implProbeContentType(Path var1) throws IOException {if (!(var1 instanceof Path)) {return null;} else {Path var2 = var1.getFileName();if (var2 == null) {return null;} else {String var3 = var2.toString();int var4 = var3.lastIndexOf(46);if (var4 >= 0 && var4 != var3.length() - 1) {String var5 = var3.substring(var4);NativeBuffer var6 = null;NativeBuffer var7 = null;Object var9;try {var6 = WindowsNativeDispatcher.asNativeBuffer(var5);var7 = WindowsNativeDispatcher.asNativeBuffer("Content Type");String var8 = queryStringValue(var6.address(), var7.address());return var8;} catch (WindowsException var13) {var13.rethrowAsIOException(var1.toString());var9 = null;} finally {var7.release();var6.release();}return (String)var9;} else {return null;}}}}在這里可以看到文件名var2之后,就在文件名上進行進一步分析和判斷,沒有讀取文件。所以,默認的detector,即使沒有實際的文件,只要根據文件名,就可以判斷一個文件的內容類型,雖然,有時不準確,例如,將一個png文件改成txt的擴展名,分析出來的結果就是:text/plain。根據類的實現,也可以通過加載自己實現的類型檢測類,然后,再調用Files.probeContentType就可以使用自己的類型探測類了。
而使用Tika調用String detect(File file)接口時,如果文件不存在,就會跑出IO異常:
Tika defaultTika = new Tika();String fileType;try{final File file = new File(fileName);fileType = defaultTika.detect(file);}catch (IOException ioEx){fileType = "Unknown";}因此,在處理上傳的文件時,使用MultipartFile.getOriginalFilename獲取的文件名生成一個File對象來獲取文件內容類型,會出IOException?異常。而且將file轉成File對象時,還可能會產生臨時文件。
不過,還好的是Tika還提供了一個針對stream流的接口:String detect(String name)?
Tika defaultTika = new Tika();MultipartFile multipartFile = multipartHttpServletRequest.getFile(key);String fileType;try{InputStream stream = multipartFile.getInputStream();fileType = defaultTika.detect(stream);}catch (IOException ioEx){fileType = "Unknown";}Tika還提供了Parser,可以通過Parser對InputStream分析得到文件的內容類型與Tika.detect(InputStream)的結果是一樣的,示例代碼如下:
public static String getMimeTypeByParser(InputStream stream) {AutoDetectParser parser = new AutoDetectParser();Metadata metadata = new Metadata();BodyContentHandler handler = new BodyContentHandler();try {parser.parse(stream, handler, metadata);} catch (IOException e) {e.printStackTrace();} catch (SAXException e) {e.printStackTrace();} catch (TikaException e) {e.printStackTrace();}return metadata.get(HttpHeaders.CONTENT_TYPE);}總結
以上是生活随笔為你收集整理的Java如何判断一个上传文件的内容类型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: layer opcode oracle,
- 下一篇: BAT 大厂Java 面试题集锦之核心