How to get the MIME Type of a .MSG file?
我已经尝试过这些方法来查找文件的MIME类型...
1 2 3 | Path source = Paths .get("C://Users/akash/Desktop/FW Internal release of MSTClient-Server5.02.04_24.msg"); System.out.println(Files.probeContentType(source)); |
上面的代码返回
如果我使用Apache的TIKA API来获取MIME类型,那么它将以文本/纯文本形式给出...
但我希望结果为
更新
我还使用
1 2 3 4 5 6 7 8 9 | 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(); |
这使我输出为
更新:
Tika API超出范围,因为它太大而无法包含在项目中...
那么如何找到MIME类型呢?
我尝试了一些可能的方法,使用tika可以得到您期望的结果,但我看不到您使用的代码,因此无法再次检查。
我尝试了不同的方式,而不是全部在代码段中:
这里是测试类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | 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; } } } |
这是输出:
1 2 3 4 5 | urlConnectionGuess null fileContentGuess null mimeTypesMap.getContentType application/octet-stream mimeutils application/msword,application/x-hwp tika application/vnd.ms-outlook |
更新后,我添加了此方法以使用Tika测试其他方式:
1 2 3 4 5 6 7 8 9 10 11 12 | 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文件进行了测试:
1 2 3 | application/vnd.ms-outlook application/octet-stream application/octet-stream |
使用重命名为msg的txt文件进行了测试:
1 2 3 | text/plain text/plain application/octet-stream |
在这种情况下,使用空构造函数的最简单方法似乎是最可靠的。
更新您可以使用Apache POI暂存器进行自己的检查,例如,这是一种获取消息的哑剧的简单实现;如果文件格式不正确(通常为
1 2 3 4 5 6 7 8 9 10 11 12 13 |
从@Duffydake的评论中得到提示,我尝试阅读魔术数字。同意MS文件头的前8个字节保持不变D0 CF 11 E0 A1 B1 1A E1(有趣的是看起来像eDoCFilE的前四个字节),但是您可以检查此链接以了解完整的头并找到文件类型。 (例如,在链接中找到一个excel文件,但是您可以使用类似的字节读取来找到msg文件类型)
如果您可以假设没有人会游玩并将.doc或.xls文件存储为.msg文件,那么您只需读取标头的前8个字节并将其与文件扩展名结合即可,例如
您可以尝试将文件转换为
1 2 3 | byte[] data = FileUtils.toByteArray("file.msg"); MagicMatch match = Magic.getMagicMatch(data); String mimeType = match.getMimeType(); |
我不确定这是否可以100%使用,但是尝试不死:)
我必须得到另一个解决方法。我发现,MS文档(doc,docx,xl??s,xlsx,msg)是具有不同扩展名的压缩文件。我尚未测试每个MS文件类型,因为它不在当前范围内
只需扩展文件,然后:
Docx:打开[Content_Types] .xml并检查它是否包含" wordprocessingml"
XlsX:打开[Content_Types] .xml并检查其是否包含" spreadsheetml"
doc:检查文件" WordDocument"
xls:检查文件"工作簿"
msg:检查文件" __properties_version1.0"
我仍在测试msg,以查看是否有更好的使用方法,但是此文件存在于已发送和未发送的消息中,因此我认为可以安全使用。