2015-06-26 13 views
17

Próbowałem te sposoby znajdowania typ MIME pliku ...Jak uzyskać typ MIME pliku .msg?

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

Powyższy kod zwraca null ...
A jeśli używam API Tika z Apache, aby uzyskać typ MIME następnie daje go jako text/plain ...

Ale chcę wynik jako application/vnd.ms-outlook

UPDATE

użyłem również MIME-Util.jar następująco kodem ...

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

To daje mi wyjście jako application/msword

UPDATE:

Tika API jest poza zakresem, ponieważ jest zbyt duża, aby uwzględnienia w projekcie ...

Więc jak mogę znaleźć typu MIME?

+0

Możesz użyć [magicznej liczby] (https://en.wikipedia.org/wiki/Magic_number_%28programming%29), aby sprawdzić plik i zwrócić typ MIME 'application/vnd.ms-outlook'. Dla .msg: 'D0 CF 11 E0 A1 B1 1A E1' – Duffydake

+0

Czy możesz podać mi odnośnik do linku, skąd otrzymałeś ten konkretny numer magiczny ... ponieważ istnieje w każdym pliku posiadającym konfigurację CFB do pakowania bajtów ... – CoderNeji

+0

Znalazłem go [tutaj] (https://billatnapier.wordpress.com/2013/04/22/magic-numbers-in-files/), ale masz rację, to wydaje się nie być poprawne. – Duffydake

Odpowiedz

5

Próbowałem niektóre z możliwych sposobów i za pomocą Tika daje wynik oczekiwany, nie widzę kod używany więc nie mogę dokładnie sprawdzić go.

Próbowałem różnych sposobów, nie wszystko we fragmencie kodu:

  1. Java 7 Files.probeContentType(path)
  2. URLConnection wykrywania MIME z nazwy pliku i typu zawartości zgadywania
  3. JDK 6 JAF API javax.activation.MimetypesFileTypeMap
  4. MimeUtil ze wszystkimi dostępnymi podklasy MimeDetector znalazłem
  5. Apache Tika
  6. Apache POI scratchpad

Tutaj klasa Test:

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; 
     } 
    } 

} 

i to jest wyjście:

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

Updated Dodałem tę metodę, aby przetestować inne sposoby z 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 
    } 
} 

przetestowane z pliku msg bez rozszerzenia:

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

przetestowane z pliku txt przemianowany na błędzie:

text/plain 
text/plain 
application/octet-stream 

Wydaje się, że najbardziej prosty sposób, za pomocą pustego konstruktora jest najbardziej wiarygodne w tym walizka.

Aktualizacja można zrobić własny sprawdzania przy użyciu Apache POI Brudnopis, na przykład jest to prosta implementacja uzyskać MIME wiadomości lub null, jeśli plik nie jest we właściwym formacie (zwykle 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; 
     } 
    } 
} 
+0

To nie daje mi pożądanego rozwiązania .... Nawet jeśli biorę plik tekstowy i zmieniam jego rozszerzenie na .msg, i używam pliku taht, aby uzyskać typ mime, to też daje wynik jako tika application/vnd.ms-outlook ... Dziękujemy za twoją pracę ... – CoderNeji

+0

Sprawdź, czy moja zaktualizowana odpowiedź może pomóc. Początkowy test tika jest oszukiwany za pomocą 'md.add (Metadata.RESOURCE_NAME_KEY," test.msg ");' sprawia, że ​​polega ono na rozszerzeniu pliku – Paizo

+0

Twój zaktualizowany kod ma ten sam problem ... Przepraszam ... Zrób następujące kroki .... 1. Utwórz plik tekstowy. 2. Zapisz. 3. Zmień nazwę rozszerzenia pliku na .msg 4. Uruchom program używając tego pliku .... Otrzymasz wynik jako application/vnd.ms-outlook – CoderNeji

2

Co można zrobić, to spróbować przekonwertować plik do byte[] a następnie użyć MimeMagic (Maven location here), aby ją obsłużyć. Coś takiego:

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

nie jestem pewien, że to będzie działać w 100%, ale spróbować nie umierać :)

+0

To też nie działa – CoderNeji

3

Biorąc przykład z komentarzem @Duffydake, próbowałem czytać magiczne liczby. Uzgodniono, że pierwsze 8 bajtów nagłówka dla plików MS pozostaje takie same D0 CF 11 E0 A1 B1 1A E1 (Interesujące, aby zobaczyć pierwszy czwarty bajt, który wygląda podobnie do eDoCFilE), ale można sprawdzić to link, jak zrozumieć kompletny nagłówek i znaleźć typ pliku. (np. w linku znajduje plik excela, ale możesz użyć podobnego czytania bajtów, aby znaleźć typ pliku msg)

Jeśli możesz założyć, że nikt nie będzie odtwarzać i przechowywać, plik .doc lub .xls jako Plik .msg, możesz po prostu przeczytać pierwsze 8 bajtów nagłówka i połączyć go z rozszerzeniem pliku, np. if(fileExtension.equals(".msg")&&hexHeaderString.equals('D0 CF 11 E0 A1 B1 1A E1'){mimeType=="application/vnd.ms-outlook"}

+0

Właściwie to moja aplikacja jest dla klienta i tutaj nie mogę niczego założyć ... już wypróbowałem odczyt nagłówka 8 bajtów .... Przepraszamy .. .. – CoderNeji

+0

następnie nie czytaj 8 bajtów i czytaj więcej bajtów zgodnie z linkiem. Link wyraźnie wyjaśnia, w jaki sposób można dowiedzieć się, plik jest excel z nagłówka. Możesz wypróbować podobny odczyt nagłówka, aby znaleźć plik .msg. Czy sprawdziłeś link, który wkleiłem? – Optional

0

Musiałem uzyskać kolejne obejście tego problemu. Odkryłem, że dokumenty MS (doc, docx, xls, xlsx, msg) są skompresowanymi plikami z innym rozszerzeniem. Nie testowałem każdy typ MS, jak plik jest poza bieżącym zakresie

Wystarczy rozwinąć plik oraz:

Docx: otwórz [CONTENT_TYPES] .xml i sprawdzić, czy zawiera ona „WordprocessingML”

XLSX : otwórz [CONTENT_TYPES] .xml i sprawdzić, czy zawiera ona "SpreadsheetML"

doc: sprawdzić plik "Worddocument"

xls: sprawdzić plik "skoroszytu"

msg: sprawdzić plik „__properties_version1.0”

ja wciąż testuje wiad aby sprawdzić, czy jest coś lepszego w użyciu, ale ten plik istnieje w wysłanych i niewysłane wiadomości, więc Zakładam jest bezpieczne posługiwać się.

+0

Jak mogę rozszerzyć ten – CoderNeji

+0

Pracuję w .Net, więc nie jestem pewien jak to zrobić w Javie. W moim przypadku używamy aplikacji 7zip do rozszerzenia plików. Możesz (jak zakładam) użyć wbudowanych modułów kompresji/dekompresji w twoim środowisku. Spójrz na ten post. http://stackoverflow.com/questions/9324933/what-is-a-good-java-library-to-zip-unzip-files –