欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java 读取图片的mimeType的方法

程序员文章站 2023-12-13 11:52:10
一、问题描述 在项目开发的时候,我们经常会遇到一类文件上传的问题,就是获取图片是哪种格式。很多情况下,很多人都是用后缀名去判断,如下所示。 if(filenam...

一、问题描述

在项目开发的时候,我们经常会遇到一类文件上传的问题,就是获取图片是哪种格式。很多情况下,很多人都是用后缀名去判断,如下所示。

if(filename.endswith(".png") || filename.endswith(".jpg"))
{
  //保存图片
}else{
  throw new ioexception("error file format !");
}

但是这种方式相当不可靠,我们可以尝试将zip文件、rmvb文件、css、js修改后缀名位jpg或者png上传,也可以上传到服务器,这就造成我们服务器上出现了脏数据。此外,对于有些图片文件,修改成错误的扩展名,有些浏览器可能无法显示出此图片。

二、解决方案

在计算机系统中,媒体类型的文件都有【标识符】,zip、图片本身属于媒体文件,因此我们可以通过编解码的方式判断图片是否合法。

1、判断标示方法

private static boolean isbmp(byte[] buf){
 byte[] markbuf = "bm".getbytes(); //bmp图片文件的前两个字节
 return compare(buf, markbuf);
 }
 
 private static boolean isicon(byte[] buf) {
 byte[] markbuf = {0, 0, 1, 0, 1, 0, 32, 32};
 return compare(buf, markbuf);
 }
 private static boolean iswebp(byte[] buf) {
 byte[] markbuf = "riff".getbytes(); //webp图片识别符
 return compare(buf, markbuf);
 }

 private static boolean isgif(byte[] buf) { 
 byte[] markbuf = "gif89a".getbytes(); //gif识别符
 if(compare(buf, markbuf))
 {
  return true;
 }
 markbuf = "gif87a".getbytes(); //gif识别符
 if(compare(buf, markbuf))
 {
  return true;
 }
 return false;
 }
 private static boolean ispng(byte[] buf) { 
 byte[] markbuf = {(byte) 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a}; //png识别符
  // new string(buf).indexof("png")>0 //也可以使用这种方式
 return compare(buf, markbuf);
 }

 private static boolean isjpegheader(byte[] buf) {
 byte[] markbuf = {(byte) 0xff, (byte) 0xd8}; //jpeg开始符 
 return compare(buf, markbuf);
 }
 
 private static boolean isjpegfooter(byte[] buf)//jpeg结束符
 {
 byte[] markbuf = {(byte) 0xff, (byte) 0xd9}; 
 return compare(buf, markbuf);
 }

2、核心方法

/**
 * 获取文件的mimetype
 * @param filename
 * @return
 */
 private static string getmimetype(string filename){
 try {
  string mimetype = readtype(filename);
  return string.format("image/%s", mimetype);
 } catch (ioexception e) {
  e.printstacktrace();
 }
 return null;
 }

 /**
 * 读取文件类型
 * @param filename
 * @return
 * @throws ioexception
 */
 private static string readtype(string filename) throws ioexception {
 
 fileinputstream fis = null;
 try {
  file f = new file(filename);
  if(!f.exists() || f.isdirectory() || f.length()<8) {
  throw new ioexception("the file ["+f.getabsolutepath()+"] is not image !");
  }
  
  fis= new fileinputstream(f);
  byte[] bufheaders = readinputstreamat(fis,0,8);
  if(isjpegheader(bufheaders))
  { 
  long skiplength = f.length()-2-8; //第一次读取时已经读了8个byte,因此需要减掉
  byte[] buffooters = readinputstreamat(fis, skiplength, 2);
  if(isjpegfooter(buffooters))
  {
   return "jpeg";
  }
  }
  if(ispng(bufheaders))
  {
  return "png";
  }
  if(isgif(bufheaders)){
  
  return "gif";
  }
  if(iswebp(bufheaders))
  {
  return "webp";
  }
  if(isbmp(bufheaders))
  {
  return "bmp";
  }
  if(isicon(bufheaders))
  {
  return "ico";
  }
  throw new ioexception("the image's format is unkown!");
  
 } catch (filenotfoundexception e) {
  throw e;
 }finally{
  try {
  if(fis!=null) fis.close();
  } catch (exception e) {
  }
 }
 
 }
 
 /**
 * 标示一致性比较
 * @param buf 待检测标示
 * @param markbuf 标识符字节数组
 * @return 返回false标示标示不匹配
 */
 private static boolean compare(byte[] buf, byte[] markbuf) {
 for (int i = 0; i < markbuf.length; i++) {
  byte b = markbuf[i];
  byte a = buf[i];
  
  if(a!=b){
  return false;
  }
 }
 return true;
 }
 /**
 * 
 * @param fis 输入流对象
 * @param skiplength 跳过位置长度
 * @param length 要读取的长度
 * @return 字节数组
 * @throws ioexception
 */
 private static byte[] readinputstreamat(fileinputstream fis, long skiplength, int length) throws ioexception
 {
 byte[] buf = new byte[length];
 fis.skip(skiplength); //
 int read = fis.read(buf,0,length);
 return buf;
 }

3、测试代码

正常测试

public class imagetype {
 public static void main(string[] args) { 
  string filename = "oschina.jpg";
  string type = getmimetype(filename);
  system.out.println(type);
 }
}

输出

image/jpeg

修改扩展名测试

①修改oschina.jpeg为oschina.png

②复制oschina.png删除扩展名

public class imagetype {
 public static void main(string[] args) {
 
  string filename = "oschina.png";
  string type = getmimetype(filename);
  system.out.println(type);
 
  filename = "oschina";
  type = getmimetype(filename);
  system.out.println(type);
      
 }
}

输出

image/jpeg
image/jpeg

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: