我只是想知道大多数人如何从Java文件中获取mime类型?到目前为止,我已经尝试了两个工具:JMimeMagic
&Mime-Util
。
第一个给我内存异常,第二个没有正确关闭其流。我只是想知道其他人是否拥有他们使用和正常工作的方法/库?
我只是想知道大多数人如何从Java文件中获取mime类型?到目前为止,我已经尝试了两个工具:JMimeMagic
&Mime-Util
。
第一个给我内存异常,第二个没有正确关闭其流。我只是想知道其他人是否拥有他们使用和正常工作的方法/库?
Answers:
在Java 7中,您现在可以使用Files.probeContentType(path)
。
不幸,
mimeType = file.toURL().openConnection().getContentType();
之所以不起作用,是因为使用URL会锁定文件,例如,该文件不可删除。
但是,您有:
mimeType= URLConnection.guessContentTypeFromName(file.getName());
还有以下内容,其优点是不仅可以使用文件扩展名,而且还可以浏览内容
InputStream is = new BufferedInputStream(new FileInputStream(file));
mimeType = URLConnection.guessContentTypeFromStream(is);
//...close stream
但是,正如上面的评论所建议的那样,内置的mime类型表非常有限,例如不包括MSWord和PDF。因此,如果要一概而论,您将需要使用Mime-Util(这是一个很棒的库,同时使用文件扩展名和内容)来超越内置库。
FileInputStream
成BufferedInputStream
是关键的部分-否则guessContentTypeFromStream
返回null
(通过InputStream
实例应该支持引号)
URLConnection
它可以识别的内容类型非常有限。例如,它无法检测到application/pdf
。
guessContentTypeFromName()
使用默认$JAVA_HOME/lib/content-types.properties
文件。您可以通过更改系统属性来添加自己的扩展文件System.setProperty("content.types.user.table","/lib/path/to/your/property/file");
JAF API是JDK 6的一部分。查看javax.activation
程序包。
最有趣的类是javax.activation.MimeType
-实际的MIME类型持有者-和javax.activation.MimetypesFileTypeMap
-其实例可以将MIME类型解析为文件的String的类:
String fileName = "/path/to/file";
MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();
// only by file name
String mimeType = mimeTypesMap.getContentType(fileName);
// or by actual File instance
File file = new File(fileName);
mimeType = mimeTypesMap.getContentType(file);
getContentType(File)
状态的javadoc :返回文件对象的MIME类型。此类中的实现调用 getContentType(f.getName())
。
MimetypesFileTypeMap.getDefaultFileTypeMap().getContentType(file)
使用Apache Tika,您只需要三行代码:
File file = new File("/path/to/file");
Tika tika = new Tika();
System.out.println(tika.detect(file));
如果您有一个普通的控制台,只需粘贴并运行以下代码即可使用:
@Grab('org.apache.tika:tika-core:1.14')
import org.apache.tika.Tika;
def tika = new Tika()
def file = new File("/path/to/file")
println tika.detect(file)
请记住,其API丰富,它可以解析“任何内容”。从tika-core 1.14开始,您有:
String detect(byte[] prefix)
String detect(byte[] prefix, String name)
String detect(File file)
String detect(InputStream stream)
String detect(InputStream stream, Metadata metadata)
String detect(InputStream stream, String name)
String detect(Path path)
String detect(String name)
String detect(URL url)
有关更多信息,请参见apidocs。
new Tika().detect(file.toPath())
用于基于文件扩展名的检测,而不是基于文件内容的检测
new Tika().detect(file.getPath())
,它仅使用文件扩展名
阿帕奇·蒂卡(Apache Tika)在tika-core中提供了基于流前缀中的魔术标记的mime类型检测。tika-core
不会获取其他依赖关系,这使其与当前未维护的Mime Type Detection Utility一样轻巧。
简单代码示例(Java 7),使用变量theInputStream
和theFileName
try (InputStream is = theInputStream;
BufferedInputStream bis = new BufferedInputStream(is);) {
AutoDetectParser parser = new AutoDetectParser();
Detector detector = parser.getDetector();
Metadata md = new Metadata();
md.add(Metadata.RESOURCE_NAME_KEY, theFileName);
MediaType mediaType = detector.detect(bis, md);
return mediaType.toString();
}
请注意,MediaType.detect(...)不能直接使用(TIKA-1120)。https://tika.apache.org/0.10/detection.html提供了更多提示。
Metadata.RESOURCE_NAME_KEY
可以省略(如果您没有名字或不能依靠原始名称),但是在某些情况下(例如办公文件),您会得到错误的结果。
如果您是Android开发人员,则可以使用实用程序类 android.webkit.MimeTypeMap
,将MIME类型映射到文件扩展名,反之亦然。
以下代码段可能会对您有所帮助。
private static String getMimeType(String fileUrl) {
String extension = MimeTypeMap.getFileExtensionFromUrl(fileUrl);
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mimeType = fileNameMap.getContentTypeFor("alert.gif");
如果您坚持使用Java 5-6,那么来自伺服开源产品的此实用程序类。
您只需要此功能
public static String getContentType(byte[] data, String name)
它探测内容的前几个字节,并根据该内容而不是文件扩展名返回内容类型。
我只是想知道大多数人如何从Java文件中获取mime类型?
我已经发布了SimpleMagic Java软件包,该软件包允许从文件和字节数组确定内容类型(MIME类型)。它旨在读取和运行Unix file(1)命令魔术文件,这些文件是大多数〜Unix OS配置的一部分。
我试过的Apache提卡,但它是巨大的与吨的依赖性,URLConnection
不使用文件的字节,MimetypesFileTypeMap
也只是看文件名。
使用SimpleMagic,您可以执行以下操作:
// create a magic utility using the internal magic file
ContentInfoUtil util = new ContentInfoUtil();
// if you want to use a different config file(s), you can load them by hand:
// ContentInfoUtil util = new ContentInfoUtil("/etc/magic");
...
ContentInfo info = util.findMatch("/tmp/upload.tmp");
// or
ContentInfo info = util.findMatch(inputStream);
// or
ContentInfo info = util.findMatch(contentByteArray);
// null if no match
if (info != null) {
String mimeType = info.getMimeType();
}
凑整我的5美分:
TL,DR
我使用MimetypesFileTypeMap并将不存在的任何mime(我特别需要它)添加到mime.types文件中。
现在,长读:
首先,MIME类型列表非常庞大,请参阅此处:https : //www.iana.org/assignments/media-types/media-types.xhtml
我喜欢先使用JDK提供的标准功能,如果那不起作用,我将继续寻找其他东西。
从文件扩展名确定文件类型
从1.6开始,Java具有MimetypesFileTypeMap,如上面的答案之一所示,这是确定mime类型的最简单方法:
new MimetypesFileTypeMap().getContentType( fileName );
在其原始实现中,这并没有太大作用(即,它适用于.html,但不适用于.png)。但是,添加您可能需要的任何内容类型非常简单:
png和js文件的示例条目为:
image/png png PNG
application/javascript js
有关mime.types文件格式,请参见此处的更多详细信息:https : //docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html
根据文件内容确定文件类型
从1.7开始,Java具有java.nio.file.spi.FileTypeDetector,它定义了用于以实现特定方式确定文件类型的标准API 。
要获取文件的mime类型,您只需使用“ 文件”并在代码中执行以下操作:
Files.probeContentType(Paths.get("either file name or full path goes here"));
API定义提供了支持从文件名或文件内容(魔术字节)确定文件mime类型的功能。这就是为什么probeContentType(),如果此API的实现使用提供给它的Path实际尝试打开与其关联的文件,则方法将引发IOException。
再次,香草实施这个(附带JDK中的一个)极不理想很多。
在一个遥远星系中的理想世界中,所有试图解决此文件到MIME类型问题的库都将简单地实现java.nio.file.spi.FileTypeDetector,您将放入首选实现库的jar中文件到您的类路径,就是这样。
在现实世界中,需要TL,DR部分的地方,您应该在其名称旁边找到带有最多星星的图书馆并使用它。对于这种特殊情况,我不需要一个(但;))。
我尝试了几种方法,包括@Joshua Fox说的第一种方法。但是有些不能识别频繁的模仿类型,例如PDF文件,而另一些不能被伪造文件信任(我尝试将扩展名更改为TIF的RAR文件)。我发现的解决方案(如@Joshua Fox所言)是使用MimeUtil2,如下所示:
MimeUtil2 mimeUtil = new MimeUtil2();
mimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");
String mimeType = MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(file)).toString();
如果您正在使用Servlet,并且可以使用Servlet上下文,则可以使用:
getServletContext().getMimeType( fileName );
getServletContext
啊
如果您在Linux OS上工作,则有一个命令行file --mimetype
:
String mimetype(file){
//1. run cmd
Object cmd=Runtime.getRuntime().exec("file --mime-type "+file);
//2 get output of cmd , then
//3. parse mimetype
if(output){return output.split(":")[1].trim(); }
return "";
}
然后
mimetype("/home/nyapp.war") // 'application/zip'
mimetype("/var/www/ggg/au.mp3") // 'audio/mp3'
在尝试了其他各种库之后,我选择了mime-util。
<groupId>eu.medsea.mimeutil</groupId>
<artifactId>mime-util</artifactId>
<version>2.1.3</version>
</dependency>
File file = new File("D:/test.tif");
MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");
Collection<?> mimeTypes = MimeUtil.getMimeTypes(file);
System.out.println(mimeTypes);
public String getFileContentType(String fileName) {
String fileType = "Undetermined";
final File file = new File(fileName);
try
{
fileType = Files.probeContentType(file.toPath());
}
catch (IOException ioException)
{
System.out.println(
"ERROR: Unable to determine file type for " + fileName
+ " due to exception " + ioException);
}
return fileType;
}
您只需要一行即可完成: MimetypesFileTypeMap()。getContentType(new File(“ filename.ext”))。查看完整的测试代码(Java 7):
import java.io.File;
import javax.activation.MimetypesFileTypeMap;
public class MimeTest {
public static void main(String a[]){
System.out.println(new MimetypesFileTypeMap().getContentType(
new File("/path/filename.txt")));
}
}
此代码产生以下输出:text / plain
File file = new File(PropertiesReader.FILE_PATH);
MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
String mimeType = fileTypeMap.getContentType(file);
URLConnection uconnection = file.toURL().openConnection();
mimeType = uconnection.getContentType();
我用以下代码做到了。
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MimeFileType {
public static void main(String args[]){
try{
URL url = new URL ("https://www.url.com.pdf");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
InputStream content = (InputStream)connection.getInputStream();
connection.getHeaderField("Content-Type");
System.out.println("Content-Type "+ connection.getHeaderField("Content-Type"));
BufferedReader in = new BufferedReader (new InputStreamReader(content));
}catch (Exception e){
}
}
}
Apache Tika。
<!-- https://mvnrepository.com/artifact/org.apache.tika/tika-parsers -->
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parsers</artifactId>
<version>1.24</version>
</dependency>
和两行代码。
Tika tika=new Tika();
tika.detect(inputStream);
下面的屏幕截图