Python 에서 struct 를 사용 하여 바 이 너 리 를 처리 하 는 실례 상세 설명

5779 단어 Pythonstruct2 진법
Python 에서 struct 를 사용 하여 바 이 너 리 를 처리 하 는 실례 상세 설명
어떤 때 는 python 으로 바 이 너 리 데 이 터 를 처리 해 야 합 니 다.예 를 들 어 파일 액세스,socket 작업 을 할 때 python 의 struct 모듈 을 사용 하여 완성 할 수 있 습 니 다.struct 로 c 언어의 구조 체 를 처리 할 수 있 습 니 다. 
  • struct 모듈 에서 가장 중요 한 세 가지 함 수 는 pack(),unpack(),calcsize()
  • 입 니 다.
  • pack(fmt, v1, v2, ...)     주어진 형식(fmt)에 따라 데 이 터 를 문자열 로 밀봉 합 니 다(실제로 c 구조 체 와 유사 한 바이트 흐름)
  • unpack(fmt, string)       주어진 형식(fmt)에 따라 바이트 흐름 string 을 분석 하고 해 석 된 tuple
  • 을 되 돌려 줍 니 다.
  • calcsize(fmt)                 주어진 형식(fmt)이 몇 바이트 의 메모 리 를 차지 하 는 지 계산 합 니 다. 
  • struct 에서 지원 하 는 형식 은 다음 과 같 습 니 다.
    Format
    C Type
    Python
    바이트 수
    x
    pad byte
    no value
    1
    c
    char
    string of length 1
    1
    b
    signed char
    integer
    1
    B
    unsigned char
    integer
    1
    ?
    _Bool
    bool
    1
    h
    short
    integer
    2
    H
    unsigned short
    integer
    2
    i
    int
    integer
    4
    I
    unsigned int
    integer or long
    4
    l
    long
    integer
    4
    L
    unsigned long
    long
    4
    q
    long long
    long
    8
    Q
    unsigned long long
    long
    8
    f
    float
    float
    4
    d
    double
    float
    8
    s
    char[]
    string
    1
    p
    char[]
    string
    1
    P
    void *
    long
    주 1.q 와 Q 는 기계 가 64 비트 조작 을 지원 할 때 만 재 미 있 습 니 다.
    주 2.각 형식 앞 에 숫자 가 하나 있 고 개 수 를 표시 할 수 있 습 니 다.
    주 3.s 형식 은 일정한 길 이 를 나타 내 는 문자열 입 니 다.4s 는 길이 가 4 인 문자열 을 표시 하지만 p 는 pacal 문자열 을 표시 합 니 다.
    주 4.P 는 포인터 의 길 이 를 기계 글자 의 길이 와 연결 시 키 는 데 사 용 됩 니 다.
    주 5.마지막 하 나 는 포인터 유형 을 나타 내 는 데 사용 할 수 있 으 며 4 개의 바이트 를 차지한다.
    c 의 구조 체 와 데 이 터 를 교환 하기 위해 서 는 c 또는 c+컴 파일 러 가 바이트 정렬 을 사용 하 는 것 도 고려 해 야 합 니 다.보통 4 개의 바이트 단위 의 32 비트 시스템 이기 때문에 struct 는 로 컬 기계 바이트 순서에 따라 변환 합 니 다.형식의 첫 번 째 문자 로 정렬 방식 을 바 꿀 수 있 습 니 다.정 의 는 다음 과 같 습 니 다.
    Character
    Byte order
    Size and alignment
    @
    native
    native            4 개의 바이트 를 채우다
    =
    native
    standard        원 바이트 수
    <
    little-endian
    standard        원 바이트 수
    >
    big-endian
    standard       원 바이트 수
    !
    network (= big-endian)
    standard       원 바이트 수
    사용 방법 은 fmt 의 첫 번 째 위치 에 놓 는 것 입 니 다.마치'@5s6sif'와 같 습 니 다. 
    예시 1:
    구조 체
    
    struct Header
    {
      unsigned short id;
      char[4] tag;
      unsigned int version;
      unsigned int count;
    }
    
    socket.recv 를 통 해 위의 구조 체 데 이 터 를 받 았 습 니 다.문자열 s 에 존재 합 니 다.이 제 는 분석 이 필요 합 니 다.unpack()함 수 를 사용 할 수 있 습 니 다.
    
    import struct id, tag, version, count = struct.unpack("!H4s2I", s)
    위의 형식 문자열 중!네트워크 바이트 순 서 를 사용 하여 분석 해 야 한 다 는 뜻 입 니 다.네트워크 에서 데 이 터 를 받 았 기 때문에 네트워크 에서 전송 할 때 네트워크 바이트 순 서 를 표시 합 니 다.뒤의 H 는 unsigned short id 를 표시 하고 4s 는 4 바이트 길이 의 문자열 을 표시 하 며 2I 는 unsigned int 형식의 데이터 가 두 개 있 음 을 표시 합 니 다.
    unpack 을 통 해 현재 id,tag,version,count 에 우리 의 정 보 를 저장 하 였 습 니 다.
    마찬가지 로 로 로 컬 데 이 터 를 struct 형식 으로 편리 하 게 팩 할 수 있 습 니 다.
    
    ss = struct.pack("!H4s2I", id, tag, version, count);
    pack 함 수 는 id,tag,version,count 를 지정 한 형식 에 따라 구조 체 Header 로 변환 합 니 다.ss 는 현재 문자열(실제 c 구조 체 와 유사 한 바이트 흐름)입 니 다.socket.send(ss)를 통 해 이 문자열 을 보 낼 수 있 습 니 다.
    예시 2:
    
    import struct
    a=12.34
    # a     
    bytes=struct.pack('i',a)
    
    이 때 bytes 는 string 문자열 입 니 다.문자열 은 바이트 와 a 의 바 이 너 리 에 따라 내용 이 같 습 니 다.
    다시 반작용 을 하 다
    현재 바 이 너 리 데이터 bytes 가 있 습 니 다.(사실은 문자열 입 니 다)이 를 거꾸로 python 데이터 형식 으로 변환 합 니 다.
    
    a,=struct.unpack('i',bytes)
    주의 하 세 요.unpack 은 tuple 로 돌아 갑 니 다.
    그래서 변수 가 하나 밖 에 없다 면:
    
    bytes=struct.pack('i',a)
    그럼 디 코딩 할 때 이렇게 해 야 돼 요.
    
    a,=struct.unpack('i',bytes)    (a,)=struct.unpack('i',bytes)
    a=struct.unpack(i,bytes)을 직접 사용 하면 a=(12.34,)은 원래 의 부동 소수점 이 아 닌 tuple 입 니 다.
    여러 데이터 로 구성 되 어 있다 면 이렇게 할 수 있 습 니 다.
    
    a='hello'
    b='world!'
    c=2
    d=45.123
    bytes=struct.pack('5s6sif',a,b,c,d)
    
    이 때 bytes 는 바 이 너 리 형식의 데이터 입 니 다.예 를 들 어 binfile.write(bytes)와 같은 파일 을 직접 쓸 수 있 습 니 다.
    그리고 필요 할 때 다시 읽 을 수 있 습 니 다.bytes=binfile.read()
    struct.unpack()을 통 해 python 변 수 를 디 코딩 합 니 다.
    
    a,b,c,d=struct.unpack('5s6sif',bytes)
    '5s6sif'는 fmt 라 고 하 는데 포맷 문자열 입 니 다.숫자 와 문자 로 구성 되 어 있 습 니 다.5s 는 5 자 를 차지 하 는 문자열,2i,2 개의 정수 등 을 표시 합 니 다.다음은 사용 가능 한 문자 와 유형 입 니 다.ctype 은 python 의 유형 과 일일이 대응 할 수 있 음 을 표시 합 니 다.
    메모:바 이 너 리 파일 을 처리 할 때 발생 하 는 문제
    바 이 너 리 파일 을 처리 할 때 다음 과 같은 방법 이 필요 합 니 다.
    
    binfile=open(filepath,'rb')        
    
    binfile=open(filepath,'wb')        
    
    그렇다면 binfile=open(filepath,r)과 결 과 는 어떤 차이 가 있 을 까?
    다른 점 은 두 가지 가 있다.
    첫째,'r'를 사용 할 때'0x1A'를 만나면 파일 이 끝 난 것 으로 간주 합 니 다.이것 이 바로 EOF 입 니 다.'rb'를 사용 하면 이 문제 가 존재 하지 않 습 니 다.바 이 너 리 로 쓰 고 텍스트 로 읽 으 면'0x1A'가 존재 하면 파일 의 일부분 만 읽 을 수 있다 는 것 이다.'rb'를 사용 할 때 파일 끝까지 읽 습 니 다.
    둘째,문자열 x='abcdef'에 대해 서 는 len(x)으로 길 이 를 7 로 얻 을 수 있 습 니 다.우 리 는 줄 바 꿈 문자 라 고 부 르 는데 사실은'0X0A'입 니 다.우리 가'w'즉 텍스트 방식 으로 쓸 때 windows 플랫폼 에 서 는 자동 으로'0X0A'를 두 글자'0X0D','0X0A',즉 파일 길이 가 실제로 8 로 변 한다.'r'텍스트 로 읽 을 때 자동 으로 줄 바 꿈 문자 로 변 환 됩 니 다.'wb'바 이 너 리 방식 으로 쓰 면 한 글자 가 변 하지 않 고 읽 을 때 도 그대로 읽 습 니 다."따라서 텍스트 로 쓰 고 바 이 너 리 로 읽 으 려 면 이 많은 바이트 들 을 고려 해 야 합 니 다."0x0D 는 리 턴 부호 라 고도 부른다.linux 에 서 는 변 하지 않 습 니 다.Liux 는 줄 바 꿈 을 표시 하기 위해'0X0A'만 사용 하기 때문이다.
     궁금 한 점 이 있 으 시 면 메 시 지 를 남기 거나 본 사이트 의 커 뮤 니 티 에 가서 토론 을 교류 하 세 요.읽 어 주 셔 서 감사합니다. 도움 이 되 셨 으 면 좋 겠 습 니 다.본 사이트 에 대한 지지 에 감 사 드 립 니 다!

    좋은 웹페이지 즐겨찾기