欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > java >内容正文

java

Java如何判断一个上传文件的内容类型

发布时间:2023/12/8 java 49 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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如何判断一个上传文件的内容类型的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。