대부분의 사람들이 Java의 파일에서 MIME 유형을 가져 오는 방법이 궁금합니다. 지금까지 두 가지 유틸리티를 시도했습니다 : JMimeMagic
& Mime-Util
.
첫 번째는 메모리 예외를 주었고 두 번째는 스트림을 올바르게 닫지 않습니다. 다른 사람이 올바르게 사용하고 올바르게 작동하는 방법 / 라이브러리가 있는지 궁금합니다.
대부분의 사람들이 Java의 파일에서 MIME 유형을 가져 오는 방법이 궁금합니다. 지금까지 두 가지 유틸리티를 시도했습니다 : JMimeMagic
& Mime-Util
.
첫 번째는 메모리 예외를 주었고 두 번째는 스트림을 올바르게 닫지 않습니다. 다른 사람이 올바르게 사용하고 올바르게 작동하는 방법 / 라이브러리가 있는지 궁금합니다.
답변:
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
그러나 위의 의견에서 제안한 것처럼 내장 마임 유형 표는 예를 들어 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 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));
groovy 콘솔이 있다면이 코드를 붙여 넣어 실행하면됩니다.
@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 유형 감지 유틸리티 만큼 가벼워집니다 .
간단한 코드 예제 (자바 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);
}
에서 roseindia :
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 패키지를 게시했습니다 . 대부분 ~ Unix OS 구성의 일부인 Unix 파일 (1) 명령 매직 파일을 읽고 실행하도록 설계되었습니다.
아파치 티카를 시도했지만은 거대한 종속성 톤, 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 정의는 파일 이름 또는 파일 내용 (매직 바이트)에서 파일 마임 유형을 결정하는 기능을 지원합니다. 그래서 probeContentType () 때문에이 API의 구현에서 제공된 Path를 사용하여 실제로 연관된 파일을 열려고 시도하는 경우 메소드에서 IOException이 발생합니다.
다시 바닐라 구현 (JDK와 함께 제공되는 것)은 많이 요구됩니다.
멀리 떨어져있는 은하계의 이상적인 세계에서는이 파일-투-마임 유형 문제를 해결하려는 모든 라이브러리가 단순히 구현됩니다. java.nio.file.spi.FileTypeDetector 것입니다. 선호하는 구현 라이브러리의 jar 클래스 경로에 파일을 넣으면됩니다.
TL, DR 섹션이 필요한 실제 세계에서는 이름 옆에 별이 가장 많은 라이브러리를 찾아서 사용해야합니다. 이 특별한 경우에는 (yet;) 필요하지 않습니다.
@Joshua Fox의 첫 번째 방법을 포함하여 여러 가지 방법을 시도했습니다. 그러나 일부는 PDF 파일과 같은 빈번한 mimetype을 인식하지 못하고 다른 파일은 가짜 파일로 신뢰할 수 없었습니다 (확장자가 TIF로 변경된 RAR 파일을 사용해 보았습니다). @Joshua Fox가 피상적으로 말한 것처럼 찾은 해결책은 다음과 같이 MimeUtil2 를 사용하는 것입니다.
MimeUtil2 mimeUtil = new MimeUtil2();
mimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");
String mimeType = MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(file)).toString();
서블릿으로 작업 중이고 서블릿 컨텍스트를 사용할 수있는 경우 다음을 사용할 수 있습니다.
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){
}
}
}
아파치 티카.
<!-- 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);
아래 스크린 샷