はい、あなたは間違っていませんでした、そしてそれはデジャヴではありません。 あなたはおそらく一度(定期的に)
このトピックを見ました。 それから多くの時間が経過し、バイナリデータ形式からのテキスト情報の読み取りに関する質問やアドバイスのリクエストが寄せられ、私に手紙が届き続けています。 そして、これは、トピックがプログラミングコミュニティにとって興味深く、興味深いものであることを意味します。
今年(実際には1年以上が経過しました)私は仕事を変えて、まったく異なることをしました。長い間、PHPでプログラミングしていません(正確にはプログラミングしません)。 新しいプロジェクトは私にpythonの改善(そしてその力を感じる)を余儀なくされたので、ある日曜日の夜にテキストを読むために私のライブラリのいくつかを書き直し、そして最も重要なことに改善することを決めました。 本日は、Microsoft Officeパッケージファイルの読み取りを目的とした(将来的には)若いオープンソースプロジェクト
Miette (「
yummy 」、フランス語から翻訳)を公開します。
Miettの主なタスクは、主にオフィス形式からクリアテキストを読み取ることですが、今回はさらに先に進み、不可能なことを行います。パーサーに形式を読み取らせます(少なくとも最小限)。 夕方の時間と苦しんでいる人々からの関心(そしておそらくテストと共同開発の形で実行可能な援助)がある場合、タスクは困難ですが、かなり実行可能です。 しかし、これらは単なる計画であり、いわば趣味です。
当然、Pythonは多くの点でPHPとは非常に異なっており、私の意見では、もう少し機能性があるため、プロジェクトでライブラリを構築する原理は、PHPの古い「クラフト」とは少し異なります。 この場合、開発者および顧客として、大きなブロックを1人でメモリにロードすることを禁止することにしました。 Miettは、Word自体と同様に、要求に応じて徐々にデータを読み取ります。 これにより、軽量でRAMに負担がかかりません。 将来的には、初期プロファイラーを調べて、さらに最適化する必要のある狭いネックを見つけようとします。
さらに進んで?
さらに読む前に、PHPで
cfbと
docの
古い記事とソースコードを確認することをお勧めします。
プロジェクト構造
プロジェクトは、ディレクトリで構成されます(さらに、ディレクトリは、1つまたは別の種類のファイルのリーダーを含みます)。 現在、Compound File Binary File Formatのリーダーがあります。これは、ほとんどのオフィスファイルのデータのラッパーであり、DOC(Microsoft Word)のラッパーです。 XLSおよびPPTのサポートがさらに追加されます。
CFBには、リーダーとDirectoryEntryの2つの主なオブジェクトが含まれ、その上に残りの「リーダー」が構築されます。 1つ目は、CFBストレージを構成する「ディレクトリエントリ」を操作するためのインターフェイスを提供します。 Readerクラスを使用すると、名前と番号の両方で必要なエントリにアクセスできます。 ルートエントリ(「ルートエントリ」)については、属性転送が行われました。これは、DirectoryEntryクラスで置き換えることができるように、ミニFATを使用して作業を主に整理および標準化します。
DirectoryEntryは、読み取り([サイズ])、seak(オフセット、[whence])、およびtell()の最小限のファイルインターフェイスを実装します。 これにより、「エントリ」を使用した作業が単純化され、一般的にはpythonの精神に沿ったものになります。 パラメータなしでread()を使用してエントリ全体を読み取ることはできますが、数バイトを読み取る場合、余分なビットを読み取らないという完全に有利なソリューションが得られます。 また、対応する属性を使用して、左/右の兄弟と子の「エントリ」を参照できます。これにより、CFBツリーを簡単に歩くことができます。
DocTextReaderの例では、CFBの使用例を見ることができます。 ご覧のとおり、PHPの実装とは異なり、少量のデータをRAMに読み込み、docファイルを常に移動します。 追加のDirectoryEntry get_byte、get_short、get_longメソッドが役立ちます。これらのメソッドは、特定の場所から対応するバイト数を読み取ります。 0 / 1TableおよびWordDocumentのメインの「オカレンス」は、クラス属性として転送されます。
この実装にはテスト文字があります;将来、DocTextReaderは、選択した位置からバイトの特定の数を読み取るための標準化されたメソッド、およびファイルクラスの他のいくつかの機能を持つ可能性があります。
使用例
最後に、ライブラリの使用例。
from doc . text import DocTextReader
doc = DocTextReader ( 'parus.doc' )
root_entry = doc . root_entry
word_document = doc . get_entry_by_name ( 'WordDocument' )
one_table = root_entry . child . left_sibling . left_sibling
fc_clx = self . word_document . get_long ( 0x01a2 )
one_table . seek ( fc_clx )
print one_table . read ( 1 )
print one_table . tell ( ) # fc_clx + 1
print doc . read ( )
PSあなたとミエッテが失望しないことを願っています。
Githubでお楽しみに:)