ファイルの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タイプを見つけることができますか?
私はいくつかの可能な方法を試しましたが、tikaを使用すると期待した結果が得られます。使用したコードが表示されないので、再確認できません。
すべてのコードスニペットではなく、さまざまな方法を試しました。
Files.probeContentType(path)
URLConnection
ファイル名とコンテンツタイプの推測からのMIME検出javax.activation.MimetypesFileTypeMap
MimeDetector
の使用可能なすべてのサブクラスを含むMimeUtilここでテストクラス:
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;
}
}
}
@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"}
あなたができることは、ファイルをbyte[]
に変換してから、MimeMagic
( Maven location here )を使用して処理することです。そんな感じ:
byte[] data = FileUtils.toByteArray("file.msg");
MagicMatch match = Magic.getMagicMatch(data);
String mimeType = match.getMimeType();
これが100%機能するかどうかは本当にわかりませんが、試してみるのは死ぬことではありません:)
別の回避策をとる必要がありました。私が見つけたのは、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使用しても安全です。