2014-12-17 1 views
1

선없이 바이너리 파일을 통해 반복. 데이터는 22 바이트의 청크로 분리되어 있으므로 22 개의 값을 포함하는 튜플 목록을 생성하려고합니다. 파일은 줄로 분리되어 있지 않으므로 파일을 반복하고 데이터를 가져 오는 방법을 찾는 데 문제가 있습니다. 내가 이렇게하면파이썬 내가 구문 분석 할 필요가 이진 파일의 일부 데이터를 가지고

그것은 잘 작동 : newList (22 개) 값의 튜플을 포함

nextList = f.read(22) 
newList = struct.unpack("BBBBBBBBBBBBBBBBBBBBBB", nextList) 

합니다. 그러나 반복되는 함수에 유사한 논리를 적용하려고하면 오류가 발생합니다. 내가 잘못 여기거야 어디 그래서 너무 확실하지 않다

Traceback (most recent call last): 
File "<pyshell#27>", line 1, in <module> 
data = getAllData() 
File "<pyshell#26>", line 5, in getAllData 
listOfAll.append(struct.unpack("BBBBBBBBBBBBBBBBBBBBBB", nextList)) 
struct.error: unpack requires a bytes object of length 22 

내가 파이썬에 비교적 새로운 해요 :

def getAllData(): 
    listOfAll = [] 
    nextList = f.read(22) 
    while nextList != "": 
     listOfAll.append(struct.unpack("BBBBBBBBBBBBBBBBBBBBBB", nextList)) 
     nextList = f.read(22) 
    return listOfAll 

data = getAllData() 

날이 오류를 제공합니다. 파일의 데이터가 22 바이트 섹션으로 균등하게 분할된다는 것을 알고 있으므로 문제는 아닙니다. 당신이 때 len(nextList) == 0가 실행 된 것으로보고 있기 때문에

+1

사람들은 "확실히"많은 것을 알고 있습니다. :-) 왜'인쇄 (LEN (nextList)에 repr (nextList))'은'append' 라인 전에 단지의 경우를 추가하지? 또 다른 가능성은 실패한 비교입니다 :'read'가'bytes' 객체를 반환하지 않습니까? 당신은'b "==" "'확실합니까? – DSM

+0

나는 당신이 제안한 첫 번째 일을했고, 내가 생각한 것처럼 균등하게 무너지면서 어떤 이유로 len (nextList) = 0 일 때 끝에 다시 실행 중이므로 while 문이 시작될 때 if 문을 추가했습니다. len (nextList)! = 22 인 경우 루프가 중단되고 의도 한대로 정확하게 작동합니다. 덕분에 내가 할에 대한 :) – lunadiviner

+0

을 나는'struct.unpack ("22B", nextList)를 사용하여'대신 22 명 조식을 입력하시기 바랍니다 바보 같은 실수 톤. – eryksun

답변

4

, 이것은 아마도 때문에 nextList (목록하지 않은 ..) 빈 문자열 객체와 동일하지 않은 빈 바이트 객체입니다

>>> b"" == "" 
False 

하고 그래서 당신의 라인

while nextList != "": 

의 조건은 nextList이 비어있는 경우에도 결코 사실이다. 휴식 상태가 근무로 len(nextList) != 22를 사용하여, 심지어

while nextList: 

이 충분해야하는 이유입니다.

+0

nextList 동안 다음과 같이 변경했습니다. if 문 없이도 완벽하게 작동합니다. – lunadiviner

0

read(22)은 22 그것은의 계약 어디 0 ~ 22 (포함)에서 길이의 문자열을 반환하는 길이의 문자열을 반환 보장 할 수 없습니다. 길이가 0 인 문자열은 읽을 데이터가 더 이상 없음을 나타냅니다. 파이썬에서 3 파일 객체 대신 strbytes 객체를 생성합니다. strbytes은 동일한 것으로 간주되지 않습니다.

파일 크기가 작은 경우 전체 파일을 메모리로 읽은 다음 청크로 분할하는 것이 좋습니다. 예.

listOfAll = [] 
data = f.read() 
for i in range(0, len(data), 22): 
    t = struct.unpack("BBBBBBBBBBBBBBBBBBBBBB", data[i:i+22]) 
    listOfAll.append(t) 

그렇지 않으면 읽은 데이터의 양을 확인하면서 더 복잡한 작업을 수행해야합니다.

def dataiter(f, chunksize=22, buffersize=4096): 
    data = b'' 
    while True: 
     newdata = f.read(buffersize)  
     if not newdata: # end of file 
      if not data: 
       return 
      else: 
       yield data 
       # or raise error as 0 < len(data) < chunksize 
       # or pad with zeros to chunksize 
       return 

     data += newdata 
     i = 0 
     while len(data) - i >= chunksize: 
      yield data[i:i+chunksize] 
      i += chunksize 

     try: 
      data = data[i:] # keep remainder of unused data 
     except IndexError: 
      data = b'' # all data was used 
관련 문제