2013-02-08 4 views
2

tar.gz 파일에서 하나의 파일 만 읽으려고합니다. "뒤쪽으로 허용되지 않습니다 추구 tarfile.StreamError는"tar 파일 객체를 통해 모든 작업은 잘 작동하지만 구체적인 구성원에서 읽을 때, 항상 StreamError이 코드 확인, 발생)ExFileObject의 read()가 항상 StreamError 예외를 발생시킵니다.

import tarfile 
fd = tarfile.open('file.tar.gz', 'r|gz') 
for member in fd.getmembers(): 
    if not member.isfile(): 
     continue 
    cfile = fd.extractfile(member) 
    print cfile.read() 
    cfile.close() 
fd.close() 

cfile.read를 (항상 발생

나는

감사합니다 (extractall 잘 작동) 파일에 덤프되지는 mem 내용을 읽을 필요가!

+1

파일로 투기 작동하지 않습니다 이유가 있습니까? 예를 들어'tempfile.mkdtemp'를 사용하여 디렉토리를 생성하고 거기에서 압축을 풀고 원하는 파일을 읽은 다음 디렉토리를 제거하십시오. 쓰기 가능한 파일 시스템에 액세스 할 수 없거나이 파일을 시도한 결과 성능이 용납 될 수 없다면 다른 어떤 이유도 고려하지 못할 것입니다. – abarnert

+0

'extractall'을'tmp' 디렉토리에 저장합니다. – jmunsch

답변

7

문제는이 라인 :

fd = tarfile.open('file.tar.gz', 'r|gz') 

당신은 'r|gz' 싶지 않아, 당신은 'r:gz'을 원한다.

평범한 타르볼에서 코드를 실행하면 member을 인쇄하고 test/foo을 볼 수 있습니다. 그러면 read에 동일한 오류가 발생합니다.

'r:gz'을 사용하도록 수정하면 작동합니다. the docs에서

:

mode has to be a string of the form 'filemode[:compression]'

...

For special purposes, there is a second format for mode: 'filemode|[compression]'. tarfile.open() will return a TarFile object that processes its data as a stream of blocks. No random seeking will be done on the file… Use this variant in combination with e.g. sys.stdin, a socket file object or a tape device. However, such a TarFile object is limited in that it does not allow to be accessed randomly, see Examples.

'r|gz'이가 아닌 시크 스트림이있을 때 의미하고, 그것은 단지 작업의 부분 집합을 제공한다. 안타깝게도 어떤 작업이 허용되는지 정확하게 문서화하지 않는 것으로 보이며 예제에 대한 링크가 도움이되지 않습니다. 예제 중 어느 것도이 기능을 사용하지 않기 때문입니다. 따라서 the source을 읽거나 시행 착오를 통해 파악해야합니다.

하지만 정상적인 파일이 있으므로 걱정할 필요가 없습니다. 단지 'r:gz'을 사용하십시오.

0

파일 모드 외에도 네트워크 스트림에서 seek을 시도했습니다. requests.get 파일을하려고 할 때

내가 같은 오류가 있었다, 그래서 나는 tmp 디렉토리에 모두를 추출 :

# stream == requests.get 
inputs = [tarfile.open(fileobj=LZMAFile(stream), mode='r|')] 
t = "/tmp" 
for tarfileobj in inputs:   
    tarfileobj.extractall(path=t, members=None) 
for fn in os.listdir(t): 
    with open(os.path.join(t, fn)) as payload: 
     print(payload.read()) 
관련 문제