ほとんどの人がJavaのファイルからMIMEタイプを取得する方法を単に疑問に思っていましたか?これまでのところ、2つのユーティリティを試しました:JMimeMagic
&Mime-Util
。
最初のものは私にメモリ例外を与えました、2番目はそのストリームを適切に閉じません。私は他の誰かが彼らが使用して正しく機能するメソッド/ライブラリを持っているのかと思っていましたか?
ほとんどの人がJavaのファイルからMIMEタイプを取得する方法を単に疑問に思っていましたか?これまでのところ、2つのユーティリティを試しました:JMimeMagic
&Mime-Util
。
最初のものは私にメモリ例外を与えました、2番目はそのストリームを適切に閉じません。私は他の誰かが彼らが使用して正しく機能するメソッド/ライブラリを持っているのかと思っていましたか?
回答:
Java 7では、今すぐ使用できますFiles.probeContentType(path)
。
null
のために.xml
、.png
と.xhtml
ファイル。私がひどく間違っていることをしているのかどうかはわかりませんが、それはかなりひどいようです。
残念ながら、
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 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のティカあなただけの必要な3行のコードを:
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)
new Tika().detect(file.toPath())
ファイルのコンテンツに基づく検出ではなく、ファイルの拡張子ベースの検出のみ
new Tika().detect(file.getPath())
だけで、ファイル拡張子を使用する、
Apache Tikaは、tika-coreで、ストリームプレフィックスのマジックマーカーに基づくMIMEタイプの検出を提供します。tika-core
は他の依存関係を取得しないため、現在メンテナンスされていないMIMEタイプ検出ユーティリティと同じくらい軽量になります。
変数theInputStream
を使用した単純なコード例(Java 7)および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タイプを取得する方法を単に疑問に思っていましたか?
ファイルとバイト配列からコンテンツタイプ(MIMEタイプ)を判別できるSimpleMagic Javaパッケージを公開しました。ほとんどの〜Unix OS構成の一部であるUnix file(1)コマンドマジックファイルを読み取って実行するように設計されています。
私はApache Tikaを試してみましたが、依存関係が非常に大きく、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には上記の回答の1つで指摘されているように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を使用して、コードで次のようにします。
Files.probeContentType(Paths.get("either file name or full path goes here"));
API定義は、ファイル名またはファイルコンテンツ(マジックバイト)からファイルMIMEタイプを判別するための機能を提供します。このため、probeContentType()メソッドはIOExceptionをスローします。このAPIの実装がそれに提供されたパスを使用して、関連付けられているファイルを実際に開こうとした場合です。
繰り返しますが、これ(JDKに付属するもの)のバニラ実装では、多くのことが望まれます。
はるか遠くにある銀河系の理想的な世界では、このファイルからMIMEタイプへの問題を解決しようとするこれらのすべてのライブラリーは、単にjava.nio.file.spi.FileTypeDetectorを実装するだけであり、優先する実装ライブラリーのjarをドロップします。あなたのクラスパスにファイルを入れれば、それだけです。
TL、DRセクションが必要な実世界では、名前の横に星が最も多いライブラリを見つけて使用する必要があります。この特定のケースでは、(まだ;)は必要ありません。
@Joshua Foxが最初に言った方法を含め、いくつかの方法を試しました。しかし、PDFファイルなどの頻繁なMIMEタイプを認識しないものもあれば、偽のファイルで信頼できないものもあります(拡張子を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
?
春にはMultipartFileファイル。
org.springframework.web.multipart.MultipartFile
file.getContentType();
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"))の 1行で実行できます 。完全なテストコードを見てください(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>
および2行のコード。
Tika tika=new Tika();
tika.detect(inputStream);
下のスクリーンショット