我们在对文件进行操作时,经常会用到文件的拓展名和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进行尽可能准确的获取。
如以上代码有错误或者不佳之处,欢迎指出,如有其他更好的方法,也欢迎提出一起讨论。
本文介绍了如何通过文件名和内容获取文件的拓展名及Content-Type,并提供了多种方法的实现,包括通过文件名字符串截取、Java内置方法及JMimeMagic库等。

1550

被折叠的 条评论
为什么被折叠?



