可以透過繼承 java.nio.file.spi.FileTypeDetector 的方式覆寫 detect() 的方法
例如:(範例程式碼轉錄自 [1])
import java.io.IOException; import java.nio.file.Path; import org.apache.tika.Tika; /** * Detects the mime type of files (ideally based on marker in file content) */ public class FileTypeDetector extends java.nio.file.spi.FileTypeDetector { private final Tika tika = new Tika(); @Override public String probeContentType(Path path) throws IOException { return tika.detect(path.toFile()); } }
另外從上面的用法也可以看出,其實只要產生 Tika 這個類別的實體,就可以呼叫 detect() 做所謂的 magic detection 了。
不過要注意的是,根據官方網站上的描述,雖然說對一般檔案的狀況,Tika 都可以透過藏在檔案開頭的 magic bytes 真測出檔案的類型
但這並不是總是能偵測出來的~有時也會需要依靠其他的資訊來判斷
舉例來說,官方的說明中提到 Container Aware Detection 這個問題,舉了 Word、PowerPoint 和 Apple iWork 的檔案為例
Word(*.doc)和 PowerPoint(*.ppt)的檔案實際上是使用 OLE2 包裝過的檔案類型;而 Apple iWork 是透過 ZIP 包裝的檔案
因此如果單純依照 magic bytes 做判斷,就很容易會把 *.doc 跟 *.ppt 判斷成 OLE2 檔、把 Apple iWork 判斷成 ZIP 檔。
遇到這種狀況時,Tika 建議的作法是使用 ContainerAwareDetector 去掃過整個檔案,來確認檔案的實際類型。
PS. 後來發現官方的 tutorial 文件似乎沒有更新,因為 1.3 和 1.4 版看來都沒有 ContainerAwareDetector 這個類別了。
另外在使用 Tika 之前,如果是要將 Tika 佈署到已經存在的執行環境,建議稍微注意一下 Tika 內包含的其他 library 是否跟環境中的 library 衝突
舉例來說,Tika-app 的 jar 檔本身包含了 Apache commons-lang、Apache poi、Bouncy Castle、asm 等等的 library
有可能會因為環境中已經存在這個 library,導致將 Tika 佈署上去後系統會出錯(JRE 不知道該讀哪個 library)
或者像是如果環境中使用了 Jersey(使用 asm 3.1),但是佈署了 Tika v1.4(使用 asm 4.1),會導致 asm 的版本不相容而造成 RESTful 服務失去功能。
參考資料:
1、Transparently improve Java 7 mime-type recognition with Apache Tika
2、Apache Tika
3、TikaInputStream
4、Releasing TikaInputStream resources
沒有留言:
張貼留言