web-dev-qa-db-ja.com

.MSGファイルのMIMEタイプを取得する方法

ファイルのMIMEタイプを見つけるこれらの方法を試しました...

Path source = Paths
                .get("C://Users/akash/Desktop/FW Internal release of MSTClient-Server5.02.04_24.msg");
        System.out.println(Files.probeContentType(source));

上記のコードはnull...を返します.
そして、ApacheからTIKA APIを使用してMIMEタイプを取得すると、text/plain ...

しかし、私はapplication/vnd.ms-Outlookとして結果を求めています

[〜#〜]更新[〜#〜]

また、コードでMIME-Util.jarを次のように使用しました...

MimeUtil2 mimeUtil = new MimeUtil2();
        mimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");
        RandomAccessFile file1 = new RandomAccessFile(
                "C://Users/akash/Desktop/FW Internal release of MSTClient-Server5.02.04_24.msg",
                "r");
        System.out.println(file1.length());
        byte[] file = new byte[624128];
        file1.read(file, 0, 624128);
        String mimeType = MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(file)).toString();

これにより、application/mswordとして出力されます

[〜#〜]更新[〜#〜]

Tika APIはプロジェクトに含めるには大きすぎるため、範囲外です...

では、どうすればMIMEタイプを見つけることができますか?

21
CoderNeji

私はいくつかの可能な方法を試しましたが、tikaを使用すると期待した結果が得られます。使用したコードが表示されないので、再確認できません。

すべてのコードスニペットではなく、さまざまな方法を試しました。

  1. Java 7 Files.probeContentType(path)
  2. URLConnectionファイル名とコンテンツタイプの推測からのMIME検出
  3. JDK 6 JAF API javax.activation.MimetypesFileTypeMap
  4. MimeDetectorの使用可能なすべてのサブクラスを含むMimeUtil
  5. アパッチティカ
  6. Apache POIスクラッチパッド

ここでテストクラス:

import Java.io.BufferedInputStream;
import Java.io.File;
import Java.io.FileInputStream;
import Java.io.InputStream;
import Java.net.URLConnection;
import Java.util.Collection;

import javax.activation.MimetypesFileTypeMap;

import org.Apache.tika.detect.Detector;
import org.Apache.tika.metadata.Metadata;
import org.Apache.tika.mime.MediaType;
import org.Apache.tika.parser.AutoDetectParser;

import eu.medsea.mimeutil.MimeUtil;

public class FindMime {

    public static void main(String[] args) {
        File file = new File("C:\\Users\\qwerty\\Desktop\\test.msg");

        System.out.println("urlConnectionGuess " + urlConnectionGuess(file));

        System.out.println("fileContentGuess " + fileContentGuess(file));

        MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();

        System.out.println("mimeTypesMap.getContentType " + mimeTypesMap.getContentType(file));

        System.out.println("mimeutils " + mimeutils(file));

        System.out.println("tika " + tika(file));

    }

    private static String mimeutils(File file) {
        try {
            MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");
            MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.ExtensionMimeDetector");
//          MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.OpendesktopMimeDetector");
            MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.WindowsRegistryMimeDetector");
//          MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.TextMimeDetector");
            InputStream is = new BufferedInputStream(new FileInputStream(file));
            Collection<?> mimeTypes = MimeUtil.getMimeTypes(is);
            return mimeTypes.toString();
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }

    private static String tika(File file) {
        try {
            InputStream is = new BufferedInputStream(new FileInputStream(file));
            AutoDetectParser parser = new AutoDetectParser();
            Detector detector = parser.getDetector();
            Metadata md = new Metadata();
            md.add(Metadata.RESOURCE_NAME_KEY, "test.msg");
            MediaType mediaType = detector.detect(is, md);
            return mediaType.toString();
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }

    private static String urlConnectionGuess(File file) {
        String mimeType = URLConnection.guessContentTypeFromName(file.getName());
        return mimeType;
    }

    private static String fileContentGuess(File file) {
        try {
            InputStream is = new BufferedInputStream(new FileInputStream(file));
            return URLConnection.guessContentTypeFromStream(is);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}

そしてこれは出力です:

urlConnectionGuess null
fileContentGuess null
mimeTypesMap.getContentType application/octet-stream
mimeutils application/msword,application/x-hwp
tika application/vnd.ms-Outlook

更新 Tikaで他の方法をテストするためにこのメソッドを追加しました:

private static void tikaMore(File file) {
    Tika defaultTika = new Tika();
    Tika mimeTika = new Tika(new MimeTypes());
    Tika typeTika = new Tika(new TypeDetector());
    try {
        System.out.println(defaultTika.detect(file));
        System.out.println(mimeTika.detect(file));
        System.out.println(typeTika.detect(file));
    } catch (Exception e) {
        // TODO: handle exception
    }
}

拡張子なしのmsgファイルでテスト:

application/vnd.ms-Outlook
application/octet-stream
application/octet-stream

msgに名前を変更したtxtファイルでテスト:

text/plain
text/plain
application/octet-stream

この場合、空のコンストラクターを使用する最も簡単な方法が最も信頼できるようです。

pdate Apache POIスクラッチパッドを使用して独自のチェッカーを作成できます。たとえば、これはメッセージのMIMEを取得する簡単な実装です。ファイルが適切な形式でない場合はnullです(通常はorg.Apache.poi.poifs.filesystem.NotOLE2FileException: Invalid header signature):

import org.Apache.poi.hsmf.MAPIMessage;

public class PoiMsgMime {

    public String getMessageMime(String fileName) {
        try {
            new MAPIMessage(fileName);
            return "application/vnd.ms-Outlook";
        } catch (Exception e) {
            return null;
        }
    }
}
7
Paizo

@Duffydakeのコメントからヒントを得て、マジックナンバーを読んでみました。 MSファイルのヘッダーの最初の8バイトは同じままであることに同意しましたD0 CF 11 E0 A1 B1 1A E1(eDoCFilEのように見える最初の4バイトを見るのは興味深い)これを確認できます link 完全なヘッダーを理解する方法ファイルの種類を見つけます。 (たとえば、リンクでExcelファイルが見つかりますが、同様のバイト読み取りを使用してmsgファイルタイプを見つけることができます)

誰も遊んだり、.docまたは.xlsファイルを.msgファイルとして保存したりしないと想定できる場合は、ヘッダーの最初の8バイトを読み取り、それをファイル拡張子と組み合わせることができます。例:if(fileExtension.equals(".msg")&&hexHeaderString.equals('D0 CF 11 E0 A1 B1 1A E1'){mimeType=="application/vnd.ms-Outlook"}

3
Optional

あなたができることは、ファイルをbyte[]に変換してから、MimeMagicMaven location here )を使用して処理することです。そんな感じ:

byte[] data = FileUtils.toByteArray("file.msg");
MagicMatch match = Magic.getMagicMatch(data);
String mimeType = match.getMimeType();

これが100%機能するかどうかは本当にわかりませんが、試してみるのは死ぬことではありません:)

2
user

別の回避策をとる必要がありました。私が見つけたのは、MSドキュメント(doc、docx、xls、xlsx、msg)が異なる拡張子の圧縮ファイルであることです。現在のスコープ外であるため、すべてのMSファイルタイプをテストしていません

単にファイルを展開して、

Docx:[Content_Types] .xmlを開き、「wordprocessingml」が含まれているかどうかを確認します

XlsX:[Content_Types] .xmlを開き、「spreadsheetml」が含まれているかどうかを確認します

doc:ファイル「WordDocument」を確認します

xls:ファイル「Workbook」を確認します

msg:ファイル "__properties_version1.0"を確認してください

私はまだmsgをテストして使用するより良いものがあるかどうかを確認していますが、このファイルは送信済みメッセージと未送信メッセージに存在するため、私はassume使用しても安全です。

0
Atron Seige