2016-06-16 3 views
1

나는 파이썬에 익숙하지 않기 때문에 나는 기본적인 것들을 모른다. 개체 배열이 들어있는 이진 파일이 있습니다. 저장된 객체는 전통적인 C 구조입니다. 나는 그 구조를 파이썬으로 재창조하고 그것의 객체 목록에있는 파일 내용을 읽고, 데이터를 수정하고 그것을 다시 저장하고 싶습니다. 내가 문제가있는 부분은 파일 내용을 읽는 것입니다. 나는 파일을 읽는 것에 관한 비슷한 질문을 읽었지 만 나는 가지고있는 질문에 답하지 않았다. 나는 클래스를 정의하고 클래스 멤버를 __slot__ 으로 정의하고 데이터를 pickle으로 읽으려고 시도했지만 제대로 작동하지 않았습니다. 또한 데이터 멤버 중 하나가 실제로 다른 구조의 객체를 포함하는 배열 인 것이 적절할 수 있습니다. 이 파일을 읽는 가장 좋은 방법은 무엇입니까?파이썬은 파일로부터 클래스 데이터 멤버를 읽어 들인다.

답변

0

파이썬의 struct.unpack()을 사용해야합니다. 그들이 어떤 유형인지 그리고 디스크에 어떻게 포장되어 있는지 정확하게 알아야합니다. pickle은 파이썬의 저장소 형식에만 해당되며, serialization을 파이썬 특정 항목으로 변환하지 않는 한 어떤 용도로도 사용되지 않습니다.

나는 최근에 당신은 아마 당신이 그것을 초기화 생성자를 가진 클래스를 생성하여 시작할 것 os.read()

보다 편리하게 찾을 수있는 파일로 mmap()을 사용하는 방법을 보여 주었다 막연하게 비슷한 질문 here 대답 파일 포인터, mmap 개체 및 오프셋의 일부 조합.

그러면 __init___() 메서드는 구조체의 압축을 푼 내용으로 self의 특성을 읽고 초기화합니다. 그리고 그들 모두 여기에 mmap() 또는 os.write

struct.pack을 사용하여 다시 작성하는 이러한 속성, 다음 save() 방법을 수정하는 접근 방법을 추가하는 것은 포장의 파이썬 문서의 예입니다 세 정수를 풀고 (2 16 비트 반바지는 다음에 32 비트 롱) : 데이터가 가변 길이 ... 당신은 장소에 데이터를 수정할 수 없습니다 것을 의미 할 수있다처럼

>>> from struct import * 
>>> pack('=hhl', 1, 2, 3) 
'\x00\x01\x00\x02\x00\x00\x00\x03' 
>>> unpack('=hhl', '\x00\x01\x00\x02\x00\x00\x00\x03') 
(1, 2, 3) 
>>> calcsize('hhl') 
8 

소리가 난다.

다음은 os.read()mmap을 모두 사용하는 Python2 예제입니다. 나는 /tmp/three_numbers.datdd if=/dev/zero of=/tmp/three_numbers.dat count=1 bs=1k으로 미리 만들었습니다.

import mmap 
import os 
import struct 


class ThreeNumbers(object): 

    PACK = '=hhl' 
    SIZEOF = struct.calcsize(PACK) 

    def __init__(self, fd, offset): 
     self._fd = fd 
     self._offset = offset 
     self._fd.seek(offset * self.SIZEOF) 
     self._data = os.read(fd.fileno(), self.SIZEOF) 
     self.numbers = struct.unpack(self.PACK, self._data) 

    def save(self): 
     self._fd.seek(self._offset * self.SIZEOF) 
     os.write(self._fd.fileno(), struct.pack(self.PACK, *self.numbers)) 


class ThreeNumbersMMAP(object): 

    PACK = '=hhl' 
    SIZEOF = struct.calcsize(PACK) 

    def __init__(self, mmap, offset): 
     self._mmap = mmap 
     self._offset = offset 
     self._data = mmap[offset * self.SIZEOF:(offset + 1) * self.SIZEOF] 
     self.numbers = struct.unpack(self.PACK, self._data) 

    def save(self): 
     self._mmap[self._offset * self.SIZEOF:(self._offset + 1) * self.SIZEOF] = struct.pack(self.PACK, *self.numbers) 


fd = open("/tmp/three_numbers.dat", "rb+") 

obj = ThreeNumbers(fd, 0) 
print obj.numbers 
obj.numbers = (1, 2, 3) 
obj.save() 

obj = ThreeNumbers(fd, 0) 
print obj.numbers 
obj.numbers = (0, 0, 0) 
obj.save() 

mmap = mmap.mmap(fd.fileno(), 0) 

obj = ThreeNumbersMMAP(mmap, 0) 
print obj.numbers 
obj.numbers = (1, 2, 3) 
obj.save() 

obj = ThreeNumbersMMAP(mmap, 0) 
print obj.numbers 
obj.numbers = (0, 0, 0) 
obj.save() 
관련 문제