아래 코드에서 대용량 파일을 읽습니다.이 파일은 특히 동시에 처리해야하는 두 개의 블록 중에서 특별한 구조를가집니다. 대신 앞뒤로 파일 추구의 내가 memoryview
에 싸여 두 블록을로드memoryview로 이진 파일 읽기
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 문자열에서 볼 수 있도록 구성됩니다.
- 내 트릭
file_names_block[names_record_index:]
은 (는) memoryview 마법을 사용합니까? 아니면 n^2 조각을 만드시겠습니까? 여기islice
을 사용해야합니까? - 본 것처럼 나는 null 바이트를 수동으로 찾은 다음
unpack_from
으로 진행합니다. 그러나 나는cast()
(docs?)을 메모리 뷰에서 사용할 수 있다고 How to split a byte string into separate bytes in python에서 읽었습니다. 그 방법을 사용하여 (또는 다른 트릭) 바이트 단위로 뷰를 분할 할 수 있습니까? 방금split('\x00')
에 전화 할 수 있습니까? 이것은 메모리 효율성을 유지합니까?
(파이썬 2에서) 올바른 방법에 대한 통찰력을 얻었습니다.
나는 memoryviews가 당신에게 아무것도주지 않는다고 생각하지 않는다; 'struct' 모듈과 같은 메모리 뷰는 널 종료 문자열을위한 특별한 기능을 가지고 있지 않습니다. –