2013-08-21 2 views
1

저는 여러 파일을 반복하고 각 파일의 처음 몇 백 줄을 처리하는 파이썬 코드를 작성하고 있습니다. 필자는이 코드를 확장하여 목록에있는 파일 중 하나라도 압축되어 있으면 코드를 읽는 동안 자동으로 압축을 풀어 내 코드가 항상 압축되지 않은 줄을 수신하도록합니다. 같은 본질적으로 내 코드는 현재 같습니다 파이썬에서 파일을 읽을 때 압축 해제를 자동으로 처리하는 방법은 무엇입니까?

for f in files: 
    handle = open(f) 
    process_file_contents(handle) 

위의 코드에 open을 대체 할 수있는 기능이 있습니까 f이 두 경우 일반 텍스트 또는 (등 또는 레스 햇의 bzip2) gzip으로 압축 된 텍스트 즉, 함수가 있도록 파일의 압축 해제 된 내용에 항상 파일 핸들을 반환합니까? (. 어떤 노력이 필요 단지 순차 액세스)

+0

그건 중복이 아니에요. 나는'gzip.open'을 어떻게 사용하는지 압니다. 본질적으로 파일을보고 자동으로'open','gzip.open' 또는 사용중인 압축에 적합한 다른 열린 함수를 선택하는 함수가 있는지 묻습니다. 따라서 묶음을 쓸 필요가 없습니다. 모든 가능한 열린 함수를 직접 시도하는 try/catch 문. –

+0

[this] (http://stackoverflow.com/questions/13044562/python-mechanism-to-identify-compressed-file-type-and-uncompress)와 같은 것? – Oli

답변

1

은 저도 같은 문제가 없었다 : 나는 자동으로 등

& 압축, with로 사용되는 파일 핸들을 파일 이름을 허용하고 반환하는 내 코드를 싶습니다 내 이 경우 파일 이름 확장자를 신뢰할 수 있으며 gzip과 bzip 파일 만 처리하면됩니다.

import gzip 
import bz2 

magic_dict = { 
    "\x1f\x8b\x08": gzip.open, 
    "\x42\x5a\x68": bz2.BZ2File, 
} 
max_len = max(len(x) for x in magic_dict) 

def open_by_magic(filename): 
    with open(filename) as f: 
     file_start = f.read(max_len) 
    for magic, fn in magic_dict.items(): 
     if file_start.startswith(magic): 
      return fn(filename) 

사용법 :

# cat 
for filename in filenames: 
    with open_by_suffix(filename) as f: 
     for line in f: 
      print f 

우리가 파일 이름을 신뢰하지 않는 경우

import gzip 
import bz2 

def open_by_suffix(filename): 
    if filename.endswith('.gz'): 
     return gzip.open(filename, 'rb') 
    elif filename.endswith('.bz2'): 
     return bz2.BZ2file(filename, 'r') 
    else: 
     return open(filename, 'r') 

, 우리는 (https://stackoverflow.com/a/13044946/117714에서 수정) 마법 문자열에 대한 파일의 초기 바이트를 비교할 수 있습니다 유스 케이스는 다음과 같습니다.

for f in files: 
    with open_by_suffix(f) as handle: 
     process_file_contents(handle) 
관련 문제