2010-11-30 34 views
2

タイプのないバイナリファイルを解析する最良の方法は何ですか。たとえば、EBMLファイルです。 (http://ebml.sourceforge.net/)。 EBMLは基本的にバイナリXMLファイルです。基本的には何でも保存できますが、その主な用途はMKVビデオファイル(matroska)です。Delphiでタイプされていないバイナリファイルを読み込み/解析する最も良い方法

EBMLファイルをバイトレベルで読み取るには、ヘッダーを読み込んでEBMLファイルであることを確認し、ファイルの情報を取得します。 MKVファイルは1〜30GBの巨大サイズです。

バイナリファイルは、jpeg、bmp、aviなど何でもかまいません。 私はちょうどそれらを読む方法を学びたいと思います。

+1

非常に曖昧な質問です。しかし、私の答えは助けになるかもしれません。 –

+0

EBML形式でもっと深く掘り下げる前に、私は基礎を作りたいと思っていました。 Sense EBMLは、他のほとんどのファイルタイプとは基本的にxmlの意味が異なります。 DelphiのGifやPngのサポートのように、他のコンポーネントを参考にしてみました。 – Logman

+0

ここでは、ブロックを読み込む方法を示していますが、個々のバイトを読み込む方法はありません。私はかなり新しいですが、EBML形式では可変長整数を使用しています。 – Logman

答えて

3

基本的には、例えば

const 
    MAGIC_WORD = $535B; 

type 
    TMyFileTypeHeader = packed record 
    MagicWord: word; // = MAGIC_WORD 
    Size: cardinal; 
    Version: cardinal; 
    Width: cardinal; 
    Height: cardinal; 
    ColorDepth: cardinal; 
    Title: array[0..31] of char; 
    end; 

procedure ReadFile(const FileName: string); 
var 
    f: file; 
    amt: integer; 
    FileHeader: TMyFileTypeHeader; 
begin 

    FileMode := fmOpenRead; 
    AssignFile(f, FileName); 

    try 
    Reset(f, 1); 

    BlockRead(f, FileHeader, sizeof(TMyFileTypeHeader), amt); 

    if FileHeader.MagicWord <> MAGIC_WORD then 
     raise Exception.Create(Format('File "%s" is not a valid XXX file.', [FileName])); 

    // Read, parse, and do something 

    finally 
    CloseFile(f); 
    end;  


end; 

を行い、ビットマップファイルはBITMAPINFOHEADERによって(バージョン3に)続いBITMAPFILEHEADER構造、で始まります。非圧縮のRGB画素データが続くパレット項目の任意の配列、(最も単純な場合において、ここで24ビットのフォーマットで)、続い:BBGGRRBBGGRRBBGGRR ...

はJPGを読み取り、一方、非常ありますJPGデータは圧縮されているため、多くの高度な数学が必要です(私は実際にJPG仕様に掘り下げたことはありません)。少なくとも、これは現代の多くのイメージファイルフォーマットに当てはまります。一方、BMPは自明ですが、 "最悪"のことは、画像がRLE圧縮されていることです。

ファイルを解析する「詳細」は、ファイル形式によってまったく異なります。ファイル形式の指定は、データがバイナリ形式でどのように格納されるかを開発者に指示します(上記の2つのビットマップ構造はWindowsビットマップ仕様の一部です)。これは契約のようなもので、そのようなファイルのすべてのエンコーダ/デコーダによって署名されています(文字通りではありません)。 EBMLの場合、仕様はhereと表示されます。

+1

BlockReadは、そのようにファイルを読み取るための古いTP方法です。 IMHOこれは古くから廃止されたテクニックです。ストリームを使用すると、コヒーレントなインターフェイスでさまざまなアクセスメソッド(バッファリングされたストリーム、メモリマッピングなど、実装するクラスを作成しているかぎり)を利用できるより汎用的なインターフェイスです。 –

+0

@アイサンドン:まあまあですが、完全に動作します(そして、私は多種多様なバイナリファイルタイプのために多くのエンコーダ/デコーダを書いています)。なぜ作業システムを放棄するのですか? –

3

ちょうどそう...

var MyFile: TStream; 
begin 
MyFile := TFileStream.Create(fmOpenRead, FileName); 
try 
    // Read stuff 
    MyFile.ReadBuffer(MyVariable, SizeOf(MyVariable)); 
    // etc. 
finally 
    MyFile.Free 
    end; 
+0

私はReadBuffer()の代わりにRead()を呼び出して、例外を処理する代わりに、直接読み込まれたバイト数を処理することを提案します。 –

+0

@ldsandon:ReadBufferには、ファイルから読み込めるバイト数が不十分な場合に例外が発生するという利点がありますので、自分で確認する必要はありません。あなたが見ることができるように、ある人の利点はもう一方の短所かもしれません。 – dummzeuch

0

のようにあなたがファイルをメモリマッピングすることができ、TFileStreamを使用しています。あたかもメモリにアクセスしているかのようにアクセスできます。 http://msdn.microsoft.com/en-us/library/aa366556(VS.85).aspx

+0

私はこのテクニックを理解するために、デルファイのコード/コンポーネントが必要です – Logman

関連する問題