Java 读取图片的mimeType的方法
一、问题描述
在项目开发的时候,我们经常会遇到一类文件上传的问题,就是获取图片是哪种格式。很多情况下,很多人都是用后缀名去判断,如下所示。
if(filename.endsWith(".png")||filename.endsWith(".jpg"))
{
//保存图片
}else{
thrownewIOException("Errorfileformat!");
}
但是这种方式相当不可靠,我们可以尝试将zip文件、rmvb文件、css、js修改后缀名位jpg或者png上传,也可以上传到服务器,这就造成我们服务器上出现了脏数据。此外,对于有些图片文件,修改成错误的扩展名,有些浏览器可能无法显示出此图片。
二、解决方案
在计算机系统中,媒体类型的文件都有【标识符】,zip、图片本身属于媒体文件,因此我们可以通过编解码的方式判断图片是否合法。
1、判断标示方法
privatestaticbooleanisBMP(byte[]buf){
byte[]markBuf="BM".getBytes();//BMP图片文件的前两个字节
returncompare(buf,markBuf);
}
privatestaticbooleanisICON(byte[]buf){
byte[]markBuf={0,0,1,0,1,0,32,32};
returncompare(buf,markBuf);
}
privatestaticbooleanisWEBP(byte[]buf){
byte[]markBuf="RIFF".getBytes();//WebP图片识别符
returncompare(buf,markBuf);
}
privatestaticbooleanisGIF(byte[]buf){
byte[]markBuf="GIF89a".getBytes();//GIF识别符
if(compare(buf,markBuf))
{
returntrue;
}
markBuf="GIF87a".getBytes();//GIF识别符
if(compare(buf,markBuf))
{
returntrue;
}
returnfalse;
}
privatestaticbooleanisPNG(byte[]buf){
byte[]markBuf={(byte)0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A};//PNG识别符
//newString(buf).indexOf("PNG")>0//也可以使用这种方式
returncompare(buf,markBuf);
}
privatestaticbooleanisJPEGHeader(byte[]buf){
byte[]markBuf={(byte)0xff,(byte)0xd8};//JPEG开始符
returncompare(buf,markBuf);
}
privatestaticbooleanisJPEGFooter(byte[]buf)//JPEG结束符
{
byte[]markBuf={(byte)0xff,(byte)0xd9};
returncompare(buf,markBuf);
}
2、核心方法
/**
*获取文件的mimeType
*@paramfilename
*@return
*/
privatestaticStringgetMimeType(Stringfilename){
try{
StringmimeType=readType(filename);
returnString.format("image/%s",mimeType);
}catch(IOExceptione){
e.printStackTrace();
}
returnnull;
}
/**
*读取文件类型
*@paramfilename
*@return
*@throwsIOException
*/
privatestaticStringreadType(Stringfilename)throwsIOException{
FileInputStreamfis=null;
try{
Filef=newFile(filename);
if(!f.exists()||f.isDirectory()||f.length()<8){
thrownewIOException("thefile["+f.getAbsolutePath()+"]isnotimage!");
}
fis=newFileInputStream(f);
byte[]bufHeaders=readInputStreamAt(fis,0,8);
if(isJPEGHeader(bufHeaders))
{
longskiplength=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";
}
thrownewIOException("theimage'sformatisunkown!");
}catch(FileNotFoundExceptione){
throwe;
}finally{
try{
if(fis!=null)fis.close();
}catch(Exceptione){
}
}
}
/**
*标示一致性比较
*@parambuf待检测标示
*@parammarkBuf标识符字节数组
*@return返回false标示标示不匹配
*/
privatestaticbooleancompare(byte[]buf,byte[]markBuf){
for(inti=0;i
3、测试代码
正常测试
publicclassImageType{
publicstaticvoidmain(String[]args){
Stringfilename="oschina.jpg";
Stringtype=getMimeType(filename);
System.out.println(type);
}
}
输出
image/jpeg
修改扩展名测试
①修改oschina.jpeg为oschina.png
②复制oschina.png删除扩展名
publicclassImageType{
publicstaticvoidmain(String[]args){
Stringfilename="oschina.png";
Stringtype=getMimeType(filename);
System.out.println(type);
filename="oschina";
type=getMimeType(filename);
System.out.println(type);
}
}
输出
image/jpeg
image/jpeg
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。