1

文字の配列のようなファイルを読み取ることができる PHP 関数またはクラスはありますか?

例えば:

$string = str_split('blabla');

$i = 0;

switch($string[$i]){

  case 'x':
    do_something();
    $i++;


  case 'y':
    if(isset($string[++$i]))
      do_something_else();
    else
      break;

   case 'z':
      // recursive call of this code etc..

}

を使用できることはわかっています$string = file_get_contents($file)が、問題は、800K の小さなファイル (80MB など) に大量のメモリが使用されることです。

isset() を呼び出したときにファイルからデータを自動的に読み取るクラスのようなある種の arrayaccess を使用して、上記のコードでファイルを何とか「ストリーミング」できますか? :)

4

1 に答える 1

6

とを使用fseekfgetcてファイル内をジャンプし、一度に 1 文字ずつ読み取ることができます。

// Leaves the file handle modified
function get_char($file, $char) {
   fseek($file, $char);
   return fgetc($file);
}

特に配列の動作が必要だとおっしゃいました。ArrayAccessこれをサポートするために実装するクラスを構築できます。

これはいくつかの理由で危険です:

  • $charファイルの長さを超えるインデックスを要求する入力を防ぐ必要があります
  • ファイル ハンドルは常に変更されます (他の場所で使用していない限り、問題ありません)。
  • これは非効率的である可能性があります (過去のリクエストをキャッシュすることで相殺されます)

もう少し効率的な代替手段は、ファイルを「遅延して」読み取ることです (つまり、一度にすべてではなくチャンクで読み取ります)。ここにいくつかの(テストされていない)コードがあります:

class BufferedReader {
    // The size of a chunk in bytes
    const BUFFER_SIZE = 512;

    protected $file;
    protected $data;

    function __construct($fname) {
        $this->file = fopen($fname, 'r');
    }

    function read_buffer() {
        $this->data .= fread($this->file, self::BUFFER_SIZE);
    }

    function get_char($char) {
        while ( $char >= strlen($this->data) && !feof($this->file) ) {
            $this->read_buffer();
        }

        if ( $char >= strlen($this->data) ) {
            return FALSE;
        }

        return substr($this->data, $char, 1);
    }
}
于 2012-12-08T23:18:02.710 に答える