获取文件的拓展名和content-type -- java实现

本文介绍了如何通过文件名和内容获取文件的拓展名及Content-Type,并提供了多种方法的实现,包括通过文件名字符串截取、Java内置方法及JMimeMagic库等。

我们在对文件进行操作时,经常会用到文件的拓展名和content-type,比如从网上下载文件,本地文件管理,按照文件的MIME类型打开文件等等。以下是我觉得目前我实现的比较好的几个方法。

拓展名的获取,我们常通过截取文件名字符串的方式来获取,代码如下。

//通过文件名获取拓展名
public static String getExtension(String fileName){
    int lastIndexOfDot = fileName.lastIndexOf(".");
    if(lastIndexOfDot < 0){
        return "";//没有拓展名
    }
    String extension = fileName.substring(lastIndexOfDot+1);
    return extension;
}

但是有时候需要处理的文件名没有拓展名,这种方法就失去了作用。这时我们可以通过获取文件的content-type来获取大概的拓展名,之所以说是大概,是因为不同的拓展名可以有相同的content-type,比如html和txt都是text/plain。

对于获取content-type的方法,java也提供了不少的方法。 Java获取文件Content-Type(Mime-Type) 上提供了四种方法,这里也贴出java JDK 1.7自带的方法和文章博主推荐的一种方法:

//java jdk 1.7自带
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public static String getContentType(String filePath){
    Path path = Paths.get(filePaht);  
    String contentType = null;  
    try {  
        contentType = Files.probeContentType(path);  
    } catch (IOException e) {  
        e.printStackTrace();  
    }
    return contentType; 
}

//JMimeMagic
public stativ String getFileContentType(String filePath){
    Magic parser = new Magic();
    MagicMatch match = parser.getMagicMatch(new File(filePath));  
    return match.getMimeType();
}

文件拓展名和content-type键值对

//如果有多个相同的charset类型,可以使用""代替或者指定统一的文件类型,指定的语句需要放在所有相同的语句的第一个位置
//更多类型可以访问  http://tool.oschina.net/commons
private static final String[][] MIME_StrTable = {
    //{后缀名,MIME类型}
    //Video
    {".3gp", "video/3gpp"},
    {".asf", "video/x-ms-asf"},
    {".avi", "video/x-msvideo"},
    {".m4u", "video/vnd.mpegurl"},
    {".m4v", "video/x-m4v"},
    {".mov", "video/quicktime"},
    //mp4 统一使用mp4
    {".mp4", "video/mp4"},
    {".mpg4", "video/mp4"},

    {".mpe", "video/x-mpeg"},
    //mpeg 使用相应的默认程序打开,但不添加文件拓展名
    {"", "video/mpg"},
    {".mpeg", "video/mpg"},
    {".mpg", "video/mpg"},

    //audio
    {".m3u", "audio/x-mpegurl"},
    //mp4a-latm 使用相应的默认程序打开,但不添加文件拓展名
    {"", "audio/mp4a-latm"},
    {".m4a", "audio/mp4a-latm"},
    {".m4b", "audio/mp4a-latm"},
    {".m4p", "audio/mp4a-latm"},

    //x-mpeg
    {".mp2", "x-mpeg"},
    {".mp3", "audio/x-mpeg"},

    {".mpga", "audio/mpeg"},
    {".ogg", "audio/ogg"},
    {".rmvb", "audio/x-pn-realaudio"},
    {".wav", "audio/x-wav"},
    {".wma", "audio/x-ms-wma"},
    {".wmv", "audio/x-ms-wmv"},

    //text
    //plain 使用相应的默认程序打开,但不添加文件拓展名
    {"", "text/plain"},
    {".c", "text/plain"},
    {".java", "text/plain"},
    {".conf", "text/plain"},
    {".cpp", "text/plain"},
    {".h", "text/plain"},
    {".prop", "text/plain"},
    {".rc", "text/plain"},
    {".sh", "text/plain"},
    {".log", "text/plain"},
    {".txt", "text/plain"},
    {".xml", "text/plain"},

    //统一使用html
    {".html", "text/html"},
    {".htm", "text/html"},

    {".css", "text/css"},

    //image
    //jpeg统一使用jpg
    {".jpg", "image/jpeg"},
    {".jpeg", "image/jpeg"},


    {".bmp", "image/bmp"},
    {".gif", "image/gif"},
    {".png", "image/png"},

    //application
    {"", "application/octet-stream"},
    {".bin", "application/octet-stream"},
    {".class", "application/octet-stream"},
    {".exe", "application/octet-stream"},
    {"class", "application/octet-stream"},

    {".apk", "application/vnd.android.package-archive"},
    {".doc", "application/msword"},
    {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
    {".xls", "application/vnd.ms-excel"},
    {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},

    {".gtar", "application/x-gtar"},
    {".gz", "application/x-gzip"},
    {".jar", "application/java-archive"},
    {".js", "application/x-javascript"},
    {".mpc", "application/vnd.mpohun.certificate"},
    {".msg", "application/vnd.ms-outlook"},
    {".pdf", "application/pdf"},
    //vnd.ms-powerpoint 使用相应的默认程序打开,但不添加文件拓展名
    {"", "application/vnd.ms-powerpoint"},
    {".pps", "application/vnd.ms-powerpoint"},
    {".ppt", "application/vnd.ms-powerpoint"},

    {".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
    {".rtf", "application/rtf"},
    {".tar", "application/x-tar"},
    {".tgz", "application/x-compressed"},
    {".wps", "application/vnd.ms-works"},
    {".z", "application/x-compress"},
    {".zip", "application/x-zip-compressed"},
//      {"", "*/*"}
};

创建分别以拓展名和content-type为key值得hashMap

//创建以content-type为key值的HashMap
public static HashMap<String,String> CreateMIMEMapKeyIsContentType(){

    HashMap<String,String> mimeHashMap = new HashMap<String,String>();

    for(int i = 0; i < MIME_StrTable.length; i ++){
        if(MIME_StrTable[i][1].length() > 0 && (!mimeHashMap.containsKey(MIME_StrTable[i][1]))){
            mimeHashMap.put(MIME_StrTable[i][1],MIME_StrTable[i][0]);
        }
    }
    return mimeHashMap;
}

//创建以拓展名为key值的HashMap
public static HashMap<String,String> CreateMIMEMapKeyIsExpands(){

    HashMap<String,String> mimeHashMap = new HashMap<String,String>();

    for(int i = 0; i < MIME_StrTable.length; i ++){
        if(MIME_StrTable[i][0].length() > 0 && (!mimeHashMap.containsKey(MIME_StrTable[i][0]))){
            mimeHashMap.put(MIME_StrTable[i][0],MIME_StrTable[i][1]);
        }
    }
    return mimeHashMap;
}

  利用以上的数组和两个函数,可以的到两个hashMap,这两个hashMap将用于拓展民和content-type之间的查询。
   由于不同拓展名可能有相同的content-type,所以我们这里对IME_StrTable 特殊的处理。以一下代码段说明。这里设定是一种content-type对应多种拓展名时,返回空字符串,当然也可以设定一个默认拓展名,去掉第一行,将video/mpg均返回.mpeg。

    {"", "video/mpg"},
    {".mpeg", "video/mpg"},
    {".mpg", "video/mpg"},

获取hashMap

static HashMap<String,String> mimeMapKeyIsContentType = null;
static HashMap<String,String> mimeMapKeyIsExpands = null;

//获取MIME列表的HashMap,设置Content-type为key值
public static HashMap<String,String> getMIMEMapKeyIsContentType(){
    //为了防止重复创建消耗时间和消耗资源,将mimeMapKeyIsContentType设置全局变量并赋初值null
    if(mimeMapKeyIsContentType == null){
        mimeMapKeyIsContentType = CreateMIMEMapKeyIsContentType();
    }
    return mimeMapKeyIsContentType;
}

//获取MIME列表的HashMap,设置拓展名为文件拓展名(含有".")
public static HashMap<String,String> getMIMEMapKeyIsExpands(){
    //为了防止重复创建消耗时间和消耗资源,将mimeMapKeyIsExpands设置全局变量并赋初值null
    if(mimeMapKeyIsExpands == null){
        mimeMapKeyIsExpands = CreateMIMEMapKeyIsExpands();
    }
    return mimeMapKeyIsExpands;
}

获取拓展名或content-type函数


//通过文件名获取拓展名
public static String getExtensionByCutStr(String fileName){
    int lastIndexOfDot = fileName.lastIndexOf(".");
    if(lastIndexOfDot < 0){
        return "";//没有拓展名
    }
    String extension = fileName.substring(lastIndexOfDot+1);
    return extension;
}

//通过拓展名获取content-type
public static String getContentTypeByExpansion(String expansionName){
    String expansion = expansionName;
    if(!expansion.startsWith(".")){
        expandsion = "." + expansion;
    }
    HashMap<String,String> expandMap = getMIMEMapKeyIsExpands();
    String contentType = expandMap.get(expansion);
    return contentType == null?"":contentType; //当找不到的时候就会返回空
}

//用JMimeMagic获取content-type
public stativ String getContentTypeByMagic(String filePath){
    Magic parser = new Magic();
    MagicMatch match = parser.getMagicMatch(new File(filePath));  
    return match.getMimeType();
}

//通过content-type获取拓展名
public static String getExpandByContentType(String contentType){
    HashMap<String,String> expandMap = getMIMEMapKeyIsContentType();
    String expands = expandMap.get(contentType);
    return expands == null?"":expands; //当找不到的时候就会返回空
}

封装

public static String getExtension(String filePath){
    String extension = getExtensionByCutStr(filePath);
    if(extension == ""){
        String contentType = getContentTypeByMagic(filePath);
        extension = getExpandByContentType(contentType);
    }
    return extension;
}

public static String getContentType(String filePath){
    String contentType = getContentTypeByMagic(filePath);
    if(contentType == ""){
        String extension = getExtensionByCutStr(filePath);
        contentType = getContentTypeByExpansion(extension);
    }
    return contentType;
}

整个代码其实是通过多种方式对拓展名或者content-type进行尽可能准确的获取。

如以上代码有错误或者不佳之处,欢迎指出,如有其他更好的方法,也欢迎提出一起讨论。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值