Java,Jsp,模式及框架
Web技术
Web服务器
浏览器相关
SQL语言
数据库
开发环境
软件开发及管理
网站SEO
短信及邮件服务
网页设计
电脑、硬件及网络
协同管理平台问题
电子商务
前沿技术及趋势
  当前位置:首页 - 知识积累 - Java,Jsp,模式及框架
Java获取文件类型Mime Type的各种方法
时间:2011年06月16日 

使用 javax.activation.MimetypesFileTypeMap
需要引入activation.jar这个jar包 , 他可以从下面这个网站获得http://java.sun.com/products/javabeans/glasgow/jaf.html.
这个MimetypesFileMap类会映射出一个file的Mime Type,这些Mime Type类型是在activation.jar包里面的资源文件中定义的

示例代码
 
import javax.activation.MimetypesFileTypeMap;   
  1. import java.io.File;   
  2.   
  3. class GetMimeType {   
  4.   public static void main(String args[]) {   
  5.     File f = new File("gumby.gif");   
  6.     System.out.println("Mime Type of " + f.getName() + " is " +   
  7.                          new MimetypesFileTypeMap().getContentType(f));   
  8.     // expected output :   
  9.     // "Mime Type of gumby.gif is image/gif"   
  10.   }   
  11. }  


自带的mime-type列表中的数量有限,但是它提供了方法让您可以很方便的添加更多的mime类型

MimetypesFileTypeMap 会在用户系统的很多地方去查找文件的MIME类型。当一个查找MIME类型的请求到达后,他会按照下面这个顺序去查找MIME类型

首先通过程序将文件添加到MimetypesFileTypeMap的一个实例中
查找用户的home路径下的文件 .mime.types
查找文件  <java.home>/lib/mime.types
查找文件或者资源 META-INF/mime.types
查找文件或者资源 META-INF/mimetypes.default (一般只在 activation.jar 中去查找).

当你需要处理一个传入的一般文件命名的文件的时候,这个方法是非常有趣的。结果出来的速度很快,因为只有扩展名被用来猜测文件的自然属性



使用 java.net.URL
警告:这个方法非常慢
与上面所说的匹配后缀名类似。后缀名和mime-type的映射关系被定义在[jre_home]\lib\content-types.properties这个文件中

import java.net.*;   
  1.   
  2. public class FileUtils{   
  3.   public static String getMimeType(String fileUrl)   
  4.     throws java.io.IOException, MalformedURLException   
  5.   {   
  6.     String type = null;   
  7.     URL u = new URL(fileUrl);   
  8.     URLConnection uc = null;   
  9.     uc = u.openConnection();   
  10.     type = uc.getContentType();   
  11.     return type;   
  12.   }   
  13.   
  14.   public static void main(String args[]) throws Exception {   
  15.     System.out.println(FileUtils.getMimeType("file://c:/temp/test.TXT"));   
  16.     // output :  text/plain   
  17.   }   
  18. }  


来自R. Lovelock 的笔记:
  我尝试去找一个最好的能获取mime type的类型的方法,发现你的发现很有用,但是现在我发现,可以通过URLConnection来查找,并没有像你描述的那么慢
import java.net.FileNameMap;   
  1. import java.net.URLConnection;   
  2.   
  3. public class FileUtils {   
  4.   
  5.   public static String getMimeType(String fileUrl)   
  6.       throws java.io.IOException   
  7.     {   
  8.       FileNameMap fileNameMap = URLConnection.getFileNameMap();   
  9.       String type = fileNameMap.getContentTypeFor(fileUrl);   
  10.   
  11.       return type;   
  12.     }   
  13.   
  14.     public static void main(String args[]) throws Exception {   
  15.       System.out.println(FileUtils.getMimeType("file://c:/temp/test.TXT"));   
  16.       // output :  text/plain   
  17.     }   
  18.   }  



使用 Apache Tika
Tika是lucene的子项目,它是通过已经存在的解析库在各种文档中查找并提取元数据和结构化文本内容的工具包。
这个包提供了罪行文件类型的支持,包括office2007(docs/pptx/xlsx/etc...)

Apache Tika
Tika有很多依赖包,大约有20个jar包!但是它所能做的不仅仅是检测文件类型这么简单,例如,你可以解析PDF或者DOC文件,并很容易的获取文本和元数据

import java.io.File;   
  1. import java.io.FileInputStream;   
  2.   
  3. import org.apache.tika.metadata.Metadata;   
  4. import org.apache.tika.parser.AutoDetectParser;   
  5. import org.apache.tika.parser.Parser;   
  6. import org.apache.tika.sax.BodyContentHandler;   
  7. import org.xml.sax.ContentHandler;   
  8.   
  9. public class Main {   
  10.   
  11.     public static void main(String args[]) throws Exception {   
  12.   
  13.     FileInputStream is = null;   
  14.     try {   
  15.       File f = new File("C:/Temp/mime/test.docx");   
  16.       is = new FileInputStream(f);   
  17.   
  18.       ContentHandler contenthandler = new BodyContentHandler();   
  19.       Metadata metadata = new Metadata();   
  20.       metadata.set(Metadata.RESOURCE_NAME_KEY, f.getName());   
  21.       Parser parser = new AutoDetectParser();   
  22.       // OOXMLParser parser = new OOXMLParser();   
  23.       parser.parse(is, contenthandler, metadata);   
  24.       System.out.println("Mime: " + metadata.get(Metadata.CONTENT_TYPE));   
  25.       System.out.println("Title: " + metadata.get(Metadata.TITLE));   
  26.       System.out.println("Author: " + metadata.get(Metadata.AUTHOR));   
  27.       System.out.println("content: " + contenthandler.toString());   
  28.     }   
  29.     catch (Exception e) {   
  30.       e.printStackTrace();   
  31.     }   
  32.     finally {   
  33.         if (is != null) is.close();   
  34.     }   
  35.   }   
  36. }  



使用JMimeMagic
通过检测文件后缀名去查找文件类型显然不是一个健壮的方法。JMimeMagic库提供了更健壮的检测方法,他是一个通过检查magic headers来判断文件或者流的mime 类型的java工具包

// snippet for JMimeMagic lib
//     http://sourceforge.net/projects/jmimemagic/
 
Magic parser = new Magic() ;   
  1. // getMagicMatch accepts Files or byte[],   
  2. // which is nice if you want to test streams   
  3. MagicMatch match = parser.getMagicMatch(new File("gumby.gif"));   
  4. System.out.println(match.getMimeType()) ;  



使用 mime-util

另一个工具是mime-util,这个工具可以通过 检测文件扩展名,或者检测magic header 两种技术方式来实现mime类型的检测

import eu.medsea.mimeutil.MimeUtil;   
  1. public class Main {   
  2.     public static void main(String[] args) {   
  3.         MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");   
  4.         File f = new File ("c:/temp/mime/test.doc");   
  5.         Collection<?> mimeTypes = MimeUtil.getMimeTypes(f);   
  6.         System.out.println(mimeTypes);   
  7.         //  output : application/msword   
  8.     }   
  9. }  

mime-util的比较好的一点是它是轻量级的,只依赖于slf4j一个包