370

Java を使用してファイルからメディア タイプ (MIME タイプ) を取得するにはどうすればよいですか? これまでのところ、JMimeMagic と Mime-Util を試しました。1 つ目はメモリ例外が発生し、2 つ目はストリームを適切に閉じません。

ファイルを調べて、その実際のタイプを (単に拡張子に基づいてではなく) 判別するにはどうすればよいでしょうか?

4

28 に答える 28

233

不運にも、

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 (ファイル拡張子とコンテンツの両方を使用する優れたライブラリ) を使用して、組み込みライブラリを超える必要があります。

于 2009-05-11T12:21:22.840 に答える
51

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);
于 2009-12-14T17:02:50.520 に答える
36

Apache Tikaは、ストリーム プレフィックスのマジック マーカーに基づく MIME タイプ検出をtika-coreで提供します。tika-core他の依存関係をフェッチしないため、現在メンテナンスされていないMime Type Detection Utilityと同じくらい軽量になります。

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/1.24/detection.htmlで提供されています。

于 2013-05-18T16:14:54.453 に答える
26

あなたが Android 開発者であれば、android.webkit.MimeTypeMapMIME タイプをファイル拡張子に、またはその逆にマッピングするユーティリティ クラスを使用できます。

次のコード スニペットが役立つ場合があります。

private static String getMimeType(String fileUrl) {
    String extension = MimeTypeMap.getFileExtensionFromUrl(fileUrl);
    return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
于 2012-12-15T06:23:39.707 に答える
19

ローズインディア より:

FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mimeType = fileNameMap.getContentTypeFor("alert.gif");
于 2011-08-01T13:34:59.857 に答える
17

Java 5-6 に行き詰まっている場合は、 servoy オープン ソース製品のこのユーティリティ クラスを使用してください。

この機能だけが必要です

public static String getContentType(byte[] data, String name)

コンテンツの最初のバイトをプローブし、ファイル拡張子ではなく、そのコンテンツに基づいてコンテンツ タイプを返します。

于 2013-09-05T15:20:30.407 に答える
14

ほとんどの人が Java のファイルからどのように MIME タイプをフェッチするのか疑問に思っていました。

ファイルとバイト配列からのコンテンツ タイプ (MIME タイプ) の決定を可能にするSimpleMagic Java パッケージを公開しました。ほとんどの ~Unix OS 構成の一部である Unix file(1) コマンド マジック ファイルを読み取って実行するように設計されています。

私は Apache Tika を試しましたが、大量の依存関係があり、ファイルのバイトを使用せず、ファイル名を確認するだけで巨大です。URLConnectionMimetypesFileTypeMap

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();
}
于 2013-06-25T16:07:42.463 に答える
4

@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();
于 2012-09-21T17:03:51.317 に答える
4

アパッチ・ティカ。

<!-- 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);

以下のスクリーンショット

ここに画像の説明を入力

于 2020-05-10T18:14:47.530 に答える
3

ファイルのアップロードには 2 層の検証を使用することをお勧めします。

まず、mimeType を確認して検証できます。

次に、ファイルの最初の 4 バイトを 16 進数に変換し、それをマジック ナンバーと比較する必要があります。そうすれば、ファイルの検証を確認するための非常に安全な方法になります.

于 2014-08-19T09:26:03.283 に答える
3

video/mp4MIME タイプを確認するものが見つからなかったため、独自のソリューションを作成しました。00 00 00 18 66 74 79 70 69 73 6F 6Dウィキペディアが間違っていて、ファイルの署名が正しくないことにたまたま気づきました。4 番目のバイト ( 18) とその後のすべて70(除外) は、それ以外の場合は有効なファイルの中でかなり多く変更されmp4ます。

このコードは基本的にコードのコピー/貼り付けURLConnection.guessContentTypeFromStreamですが、video/mp4.

BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(content));
String mimeType = URLConnection.guessContentTypeFromStream(bis);

// Goes full barbaric and processes the bytes manually
if (mimeType == null){
    // These ints converted in hex ar:
    // 00 00 00 18 66 74 79 70 69 73 6F 6D
    // which are the file signature (magic bytes) for .mp4 files
    // from https://www.wikiwand.com/en/List_of_file_signatures
    // just ctrl+f "mp4"
    int[] mp4_sig = {0, 0, 0, 24, 102, 116, 121, 112};

    bis.reset();
    bis.mark(16);
    int[] firstBytes = new int[8];
    for (int i = 0; i < 8; i++) {
        firstBytes[i] = bis.read();
    }
    // This byte doesn't matter for the file signature and changes
    mp4_sig[3] = content[3];

    bis.reset();
    if (Arrays.equals(firstBytes, mp4_sig)){
        mimeType = "video/mp4";
    }
}

.mp410 個の異なるファイルに対して正常にテストされました。

編集:これは、多くの種類のサンプルを見つけることができる便利なリンク (まだオンラインの場合) です。私はそれらのビデオを所有しておらず、誰が所有しているのかもわかりませんが、上記のコードをテストするのに役立ちます。

于 2020-11-03T21:44:13.460 に答える
1

春のMultipartFileファイルで。

org.springframework.web.multipart.MultipartFile

file.getContentType();

于 2016-04-26T11:33:13.907 に答える
0
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;
}
于 2016-11-23T13:26:18.497 に答える
0

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'
于 2014-12-07T11:17:48.840 に答える
0

次のコードでそれを行いました。

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){

        }
    }
}
于 2019-07-31T20:33:50.153 に答える
0

他のさまざまなライブラリを試した後、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);
于 2016-05-26T12:35:24.087 に答える