2012-01-20 14 views
1

私は現在、仕事を得るために私のクラスでは、次の2つのメソッドを使用しています:ファイル内の16進数文字列をPHPで検索していますか?

function xseek($h,$pos){ 
    rewind($h); 
    if($pos>0) 
    fread($h,$pos); 
} 
function find($str){ 
    return $this->startingindex($this->name,$str); 
} 

function startingindex($a,$b){ 
    $lim = 1 + filesize($a) - strlen($b)/2; 
    $h = fopen($a,"rb"); 
    rewind($h); 
    for($i=0;$i<$lim;$i++){ 
     $this->xseek($h,$i); 
     if($b==strtoupper(bin2hex(fread($h,strlen($b)/2)))){ 
      fclose($h); 
      return $i; 
     } 
    } 
    fclose($h); 
    return -1; 
} 

私は特にPHPのために、これは非常に非効率的であると認識が、私は私のホスティング上の他の言語を許可されていませんよ計画。

私はいくつかのテストを実行し、ファイルの先頭に向かっているときはすぐに実行され、オフセットが返されます。ただし、16進文字列が見つからない場合は、しばらくページがハングします。これは私がPHPでテストした最後の時間にページがぶら下がってしまったために私の中を殺してしまいました。私のウェブホストはあまりにも多くのCPU時間のために私のサイトを24時間閉鎖しました。

ファイル内の16進文字列のオフセットを見つけるより良い方法がありますか?実行のスピードを上げるために改善できる点がいくつかありますか?

ファイルの内容全体を1つの16進文字列に読み込み、strrposを使用していましたが、最大メモリを超えるエラーが発生しました。私はファイルを切断し、大きな断片をstrrposで検索した方が良い方法でしょうか?

編集:

指定するには、私はゲームのための設定ファイルを扱っています。設定とそれらの値は、設定の前に32ビットの整数があるブロック内にあり、次に設定の前に32ビットのintがあり、その後に値が格納されます。どちらのintも次の文字列の長さを表します。たとえば、設定が「テスト」で、値が「0」の場合は、16進数で表示されます(00000004746573740000000130)。これに言及すると、これは悪い方法です。あなたは何をお勧めします?

編集2:

私は私が許可さのstrrposを試してみましたが、それは私がしようとしてきた方法よりも非常に遅かったんだな最大メモリを下回ったファイルを試してみました。

編集3:チャールズへの返信で:

不明何が設定ブロックとどこが始まるの長さです。私が知っているのは、最初と最後の設定が何であるかです。私はこれらの検索方法を使って最初と最後の設定の場所を見つけ、設定ブロックの長さを決定しています。私は親ブロックがどこから始まるかも知っています。設定ブロックは、親に50バイト以下であるため、最初の設定の検索を開始し、検索の距離を制限することができます。問題は、私も最後の設定を見つける必要があるということです。設定ブロックの長さは可変で、任意の長さにすることができます。私は、ゲームの想定通りにファイルを読むことができました。設定の大きさを読んだり、設定を読んだり、値の大きさを読んだり、値を読み込んだりすると、値-1のバイトに達するか、FFヘックスで。最初の設定の検索を制限し、設定を正しく読み込むことの組み合わせがこれをはるかに効率的にするでしょうか?

+0

この16進数検索ルーチンを使用して実際に何をしているのか詳しく教えてください。これは、ファイルのスプライシングについての質問に直接関係しているようです。全体のタスクを実行するためのより良い方法があるかもしれません。 – Charles

+0

@Charles、私はゲームの設定ファイルを扱っています。設定とそれらの値は、設定の前に32ビットの整数があるブロック内にあり、次に設定の前に32ビットのintがあり、その後に値が格納されます。どちらのintも次の文字列の長さを表します。たとえば、設定が "test"で値が "0"の場合、16進数で表示されます(00000004746573740000000130)。これに言及したので、これは悪いことだと思われます。あなたは何をお勧めします? – mowwwalker

+1

まあ、すべてのもののように、それは種類によって異なります。見つかった文字列がファイルの内部で深い場合、パフォーマンスが低下することに言及しました。ファイルはどのくらいの大きさになりますか?あなたが探しているものはファイル全体に散らばっているのですか、それとも比較的予測可能な場所にありますか? – Charles

答えて

2

ガベージコードがたくさんあります。たとえば、このコードはほとんど何もしていません。

function xseek($h,$pos){ 
    rewind($h); 
    if($pos>0) 
    fread($h,$pos); 
} 

ファイルの先頭から毎回読み込むためです。 Furthemore、あなたがそれを返さないなら、何かを読む必要があるのはなぜですか?あなたはfseek()のルークですか?

バイナリファイルで16進文字列を検索する必要がある場合は、http://pastebin.com/fpDBdsvV(いくつかのバグや問題がある場合は教えてください)のようなものを使用する方がよいでしょう。

しかし、あなたがゲームの設定ファイルを解析している場合、私はあなたが設定がどこの場所に求めること fseek()fread()unpack()を使用することをお勧めする、バイトの部分を読んで、PHPの変数の型にそれを解凍します。

+0

fseekが正常に動作しませんでした。 – mowwwalker

+2

fseekは99%のケースで正しく機能しません。私はPHPでバイナリデータの扱いで多くの作業をしましたが、すべては問題ありませんでした。 – Timur

+0

それは今働いているようですが、以前は信頼できないのかどうかは分かりませんでした。 – mowwwalker

関連する問題