如何检查上传的文件是否是图像或其他文件?

在我的web应用程序中,我有一个图像上传模块。 我想检查上传的文件是否是图像文件或任何其他文件。 我在服务器端使用Java。

该图像读取为BufferedImage在Java中,然后我写它与磁盘ImageIO.write()

我应该如何检查BufferedImage ,不pipe它是一个图像还是其他的东西?

任何build议或链接,将不胜感激。

我假设你在servlet上下文中运行这个。 如果根据文件扩展名检查内容types是否合理,则使用ServletContext#getMimeType()获取MIMEtypes(内容types)。 只要检查它是否开始与image/

 String fileName = uploadedFile.getFileName(); String mimeType = getServletContext().getMimeType(fileName); if (mimeType.startsWith("image/")) { // It's an image. } 

默认的MIMEtypes在servletcontainer的web.xml中定义。 例如Tomcat,它位于/conf/web.xml 。 您可以在/WEB-INF/web.xml应用程序的/WEB-INF/web.xml中扩展/覆盖它,如下所示:

 <mime-mapping> <extension>svg</extension> <mime-type>image/svg+xml</mime-type> </mime-mapping> 

但是,这并不能阻止你通过改变文件扩展名来欺骗你的用户。 如果您想要覆盖这一点,那么您也可以根据实际的文件内容来确定MIMEtypes。 如果只检查BMP,GIF,JPG或PNGtypes(但不包括TIF,PSD,SVG等),那么您可以直接将它提供给ImageIO#read()并检查它是否不抛出exception。

 try (InputStream input = uploadedFile.getInputStream()) { try { ImageIO.read(input).toString(); // It's an image (only BMP, GIF, JPG and PNG are recognized). } catch (Exception e) { // It's not an image. } } 

但是,如果您想要覆盖更多的图片types,请考虑使用第三方库,通过嗅探文件头来完成所有工作。 例如支持BMP,GIF,JPG,PNG,TIF和PSD(但不支持SVG)的JMimeMagic或Apache Tika 。 Apache Batik支持SVG。 下面的例子使用JMimeMagic:

 try (InputStream input = uploadedFile.getInputStream()) { String mimeType = Magic.getMagicMatch(input, false).getMimeType(); if (mimeType.startsWith("image/")) { // It's an image. } else { // It's not an image. } } 

你可以在必要时使用组合,并胜过其中一个。

也就是说,您不一定需要ImageIO#write()将上传的图像保存到磁盘。 只需将获得的InputStream直接写入Path或任何OutputStreamFileOutputStream ,通常的Java IO方式就足够了(另请参阅将上载的文件保存在servlet应用程序中的推荐方法 ):

 try (InputStream input = uploadedFile.getInputStream()) { Files.copy(input, new File(uploadFolder, fileName).toPath()); } 

除非你想收集一些像尺寸的图像信息和/或想操纵它(裁剪/resize/旋转/转换/等),当然。

我用org.apache.commons.imaging.Imaging在我的情况。 下面是一段代码来检查图像是否是一个JPEG图像。 如果上传的文件不是图像,则抛出ImageReadException。

  try { //image is InputStream byte[] byteArray = IOUtils.toByteArray(image); ImageFormat mimeType = Imaging.guessFormat(byteArray); if (mimeType == ImageFormats.JPEG) { return; } else { // handle image of different format. Ex: PNG } } catch (ImageReadException e) { //not an image } 

这是内置到JDK中,只需要一个stream支持

 byte[] data = ; InputStream is = new BufferedInputStream(new ByteArrayInputStream(data)); String mimeType = URLConnection.guessContentTypeFromStream(is); //...close stream