1

以下のコードで、特別な構造を持つ大きなファイルを読み取りました。特に、同時に処理する必要がある 2 つのブロックがあります。ファイルを前後にシークする代わりに、memoryview呼び出しでラップされたこれらの 2 つのブロックをロードします。

with open(abs_path, 'rb') as bsa_file:
    # ...
    # load the file record block to parse later
    file_records_block = memoryview(bsa_file.read(file_records_block_size))
    # load the file names block
    file_names_block = memoryview(bsa_file.read(total_file_name_length))
    # close the file
file_records_index = names_record_index = 0
for folder_record in folder_records:
    name_size = struct.unpack_from('B', file_records_block, file_records_index)[0]
    # discard null terminator below
    folder_path = struct.unpack_from('%ds' % (name_size - 1),
        file_records_block, file_records_index + 1)[0]
    file_records_index += name_size + 1
    for __ in xrange(folder_record.files_count):
        file_name_len = 0
        for b in file_names_block[names_record_index:]:
            if b != '\x00': file_name_len += 1
            else: break
        file_name = unicode(struct.unpack_from('%ds' % file_name_len,
            file_names_block,names_record_index)[0])
        names_record_index += file_name_len + 1

ファイルは正しく解析されていますが、mamoryview インターフェイスを初めて使用するため、正しく解析されているかどうかわかりません。file_names_block は、null で終了する C 文字列で見られるように構成されます。

  1. 私のトリックfile_names_block[names_record_index:]は memoryview マジックを使用していますか、それとも n^2 スライスをいくつか作成しますか? ここで使用する必要がありisliceますか?
  2. ご覧のとおり、ヌル バイトを手動で探してから に進みますunpack_from。しかし、メモリビューで使用できるPythonでバイト文字列を個別のバイトに分割する方法cast()(ドキュメント?)を読みました-それ(または別のトリック)を使用してビューをバイト単位で分割する方法はありますか? 電話してもsplit('\x00')いいですか?これはメモリ効率を維持しますか?

これを行う正しい方法についての洞察をいただければ幸いです(python 2)。

4

1 に答える 1