*.doc ファイルが Java または ColdFusion を使用した RTF であるかどうかを確認する最良の方法
-
16-09-2019 - |
質問
したがって、約4,000ワードのドキュメントがあり、そこからテキストを抽出してデータベーステーブルに挿入しようとしています。これは、プロセッサが次のようなドキュメントを検出するまでスムーズに機能します。 *.doc
ファイル拡張子は異なりますが、ファイルが実際に RTF であると判断されます。POI が RTF をサポートしていないことがわかりましたが、それは問題ありませんが、RTF がサポートされているかどうかを判断する方法が必要です。 *.doc
ファイルは実際には RTF であるため、ファイルを無視して処理を続行することを選択できます。
これを克服するために、ColdFusion の MimeTypeUtils を使用するなど、いくつかの手法を試しましたが、ファイル拡張子に基づいて MIME タイプを想定しているようで、依然として RTF を application/msword として分類しているようです。かどうかを確認する他の方法はありますか? *.doc
RTFですか?ご協力いただければ幸いです。
解決
CF8 との互換性:
<cffunction name="IsRtfFile" returntype="Boolean" output="false">
<cfargument name="FileName" type="String" />
<cfreturn Left(FileRead(Arguments.FileName),5) EQ '{\rtf' />
</cffunction>
以前のバージョンの場合:
<cffunction name="IsRtfFile" returntype="Boolean" output="false">
<cfargument name="FileName" type="String" />
<cfset var FileData = 0 />
<cffile variable="FileData" action="read" file="#Arguments.FileName#" />
<cfreturn Left(FileData,5) EQ '{\rtf' />
</cffunction>
アップデート: CF8/互換性のあるより良い答え。ファイル全体をメモリにロードしないようにするには、次の手順を実行して最初の数文字だけをロードします。
<cffunction name="IsRtfFile" returntype="Boolean" output="false">
<cfargument name="FileName" type="String" />
<cfset var FileData = 0 />
<cfloop index="FileData" file="#Arguments.FileName#" characters="5">
<cfbreak/>
</cfloop>
<cfreturn FileData EQ '{\rtf' />
</cffunction>
コメントに基づいて:
ここでは、「これはどのような形式ですか」タイプの関数を生成する非常に簡単な方法を示します。完璧ではありませんが、アイデアは得られます...
<cffunction name="determineFileFormat" returntype="String" output="false"
hint="Determines format of file based on header of the file's data."
>
<cfargument name="FileName" type="String"/>
<cfset var FileData = 0 />
<cfset var CurFormat = 0 />
<cfset var MaxBytes = 8 />
<cfset var Formats =
{ WordNew : 'D0,CF,11,E0,A1,B1,1A,E1'
, WordBeta : '0E,11,FC,0D,D0,CF,11,E0'
, Rtf : '7B,5C,72,74,66' <!--- {\rtf --->
, Jpeg : 'FF,D8'
}/>
<cfloop index="FileData" file="#Arguments.FileName#" characters="#MaxBytes#">
<cfbreak/>
</cfloop>
<cfloop item="CurFormat" collection="#Formats#">
<cfif Left( FileData , ListLen(Formats[CurFormat]) ) EQ convertToText(Formats[CurFormat]) >
<cfreturn CurFormat />
</cfif>
</cfloop>
<cfreturn "Unknown"/>
</cffunction>
<cffunction name="convertToText" returntype="String" output="false">
<cfargument name="HexList" type="String" />
<cfset var Result = "" />
<cfset var CurItem = 0 />
<cfloop index="CurItem" list="#Arguments.HexList#">
<cfset Result &= Chr(InputBaseN(CurItem,16)) />
</cfloop>
<cfreturn Result />
</cffunction>
もちろん、これはすべて、多くの一般的なテキストベースのもの (CFM、CSS、JS など) を含む「ヘッダーなし」形式では機能しないことを指摘しておく価値があります。
他のヒント
すべてのRTFファイルの最初の5つのバイトはする必要があります:
{\rtf
そうでない場合は、RTFファイルではありません。
Wikipeida記事のリンクます。
DOCファイル(Wordの'97以来、少なくともそれらの)「Windowsの化合物のバイナリフォーマット」と呼ばれるもの、ここではPDFに文書を使用しますに。それによると、これらのドキュメントファイルは、次の順序で開始します:
0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1
または古いベータファイルでます:
0x0e, 0x11, 0xfc, 0x0d, 0xd0, 0xcf, 0x11, 0xe0
単語のWikipediaの記事によると、少なくとも5種類のフォーマットが前97年にありました。
{\ RTF形式をお探しすることはあなたの最善の策である必要があります。
幸運、このことができます願っています。
byteArray を文字列に変換できます
<cfset str = createObject("java", "java.lang.String").init(bytes)>
POI のソースから hasxxxHeader メソッドを試すこともできます。入力ファイルが POI で処理できるものであるかどうかを判断します。OLE または OOXML。しかし、他の誰かが単純な try/catch を使用して問題のあるファイルをスキップすることを提案したと思います。そうしたくない理由はありますか?それはより簡単なオプションのように思えます。
アップデート:Peter の CF 8 の機能を使用するという提案も機能するでしょう
<cfset input = FileOpen(pathToYourFile)>
<cfset bytes = FileRead(input , 8)>
<cfdump var="#bytes#">
<cfset FileClose(input)>
あなたはへのアクセスを提供するドロイドのツール(デジタル録音のオブジェクト識別)、とのファイルを特定しようとすることができ Pronom技術的なレジストリでます。