파일에 액세스하거나 소켓 작업을 수행할 때와 같이 바이너리 데이터를 처리하기 위해 Python을 사용해야 하는 경우가 있습니다. 이때 Python의 구조체 모듈을 사용하여 C 언어에서 구조체를 처리할 수 있습니다.
struct 모듈에서 가장 중요한 세 가지 함수는 pack(), unpack(), calcsize()입니다.pack(fmt, v1, v2, ...)는 주어진 형식(fmt)에 따라 데이터를 string (실제로는 C 구조와 유사한 바이트 스트림입니다)unpack(fmt, string) 주어진 형식(fmt)에 따라 바이트 스트림 문자열을 구문 분석하고 구문 분석된 튜플을 반환합니다.calcsize(fmt) 주어진 개수를 계산합니다. 바이트의 메모리가 포맷(fmt)을 차지합니까? 구조체에서 지원되는 형식은 다음과 같습니다. Format C 유형 Python 바이트 수 x 패드 바이트 값 없음 1c char 문자열 길이 1 1 b signed char 정수 1B unsigned char 정수 1? _Bool bool 1h short 정수 2H unsigned short 정수 2i int 정수 4I unsigned int 정수 또는 long 4l long 정수 4
L unsigned long long 4q long long long 8Q unsigned long long long 8f float float 4d double float 8s char[] 문자열 1p char[] 문자열 1
P void * longNote 1.q와 Q는 기기가 64비트 작업을 지원할 때만 유용합니다Note 2. 각 형식 앞에 숫자를 나타내는 숫자가 있을 수 있습니다Note 3.s 형식 특정 길이의 문자열을 나타냅니다. 4s는 길이 4의 문자열을 나타내지만 p는 파스칼 문자열을 나타냅니다참고 4. P는 포인터를 변환하는 데 사용되며 그 길이는 기계어 길이와 관련됩니다참고 5. 마지막 하나는 4바이트를 차지하는 포인터 유형을 나타내는 데 사용됩니다.C의 구조와 데이터를 교환하려면 일부 C 또는 C++ 컴파일러가 일반적으로 4바이트 단위로 바이트 정렬을 사용한다는 점을 고려해야 합니다. 32비트 시스템 , 따라서 구조체는 로컬 머신 바이트 순서에 따라 변환됩니다. 형식의 첫 번째 문자를 사용하여 정렬을 변경할 수 있습니다. 정의는 다음과 같습니다. 문자 바이트 순서 크기 및 정렬@ 네이티브 네이티브 구성 4 바이트 = 원래 바이트 수에 따른 기본 표준4a13e0a2163bae2a6d04d06f4dc8655e 원래 바이트 수에 따른 빅 엔디안 표준! endian) standard Press 원래 바이트 수는 '@5s6sif'와 마찬가지로 fmt의 첫 번째 위치에 사용됩니다.예1: 구조는 다음과 같습니다.
struct Header { unsigned short id; char[4] tag; unsigned int version; unsigned int count; }위의 구조 데이터를 통해 받았습니다. 소켓.recv는 문자열 s에 존재합니다. 이제 이를 구문 분석해야 하며 unpack() 함수를 사용할 수 있습니다.
import struct id, tag, version, count = struct.unpack("!H4s2I", s)위 형식 문자열에서 !는 구문 분석에 네트워크 바이트 순서를 사용한다는 의미입니다. 우리의 데이터는 네트워크에서 수신된 것이며 네트워크를 통해 전송될 때 네트워크 바이트 순서입니다. 다음 H는 부호 없는 짧은 ID를 나타내고, 4s는 4바이트 길이의 문자열을 나타내고, 2I는 두 개의 부호 없는 int 유형 데이터를 나타냅니다.
압축 해제를 통해 이제 정보가 id, 태그, 버전 및 개수로 저장되었습니다. 마찬가지로 로컬 데이터를 구조체 형식으로 압축하는 것도 매우 편리합니다.
ss = struct.pack("!H4s2I", id, tag, version, count);pack 함수는 id, 태그, 버전을 넣습니다. 및 count는 지정된 형식에 따라 Header 구조로 변환됩니다. ss는 이제 문자열입니다(실제로는 c 구조와 유사한 바이트 스트림). 이 문자열은 go out을 통해 전송될 수 있습니다. 예제 2:
import struct a=12.34 #将a变为二进制 bytes=struct.pack('i',a)이때 bytes는 문자열 문자열이고, 그 문자열은 바이트 단위의 바이너리 저장 내용과 동일합니다. 그런 다음 반대 작업을 수행하고 기존 바이너리 데이터 바이트(실제로는 문자열)를 Python 데이터 유형으로 변환합니다. #unpack이 튜플을 반환한다는 점에 유의하세요!!
a,=struct.unpack('i',bytes)여러 개로 구성되는 경우 다음으로 구성됩니다.
a='hello' b='world!' c=2 d=45.123 bytes=struct.pack('5s6sif',a,b,c,d)이때 바이트는 바이너리 형식의 데이터이고, binfile.write(bytes)와 같은 파일에 직접 쓸 수 있습니다. 그런 다음 필요할 때 읽을 수 있습니다. bytes=binfile .read() 그런 다음 struct.unpack()을 통해 Python 변수로 디코딩됩니다.
a,b,c,d=struct.unpack('5s6sif',bytes)'5s6sif'는 fmt라고 하며 숫자와 문자로 구성된 형식화된 문자열입니다. 5자의 문자열. 2i는 2개의 정수 등을 의미합니다. 다음은 사용 가능한 문자 및 유형입니다. ctype은 Python의 유형에 일대일로 대응할 수 있음을 의미합니다. 참고: 바이너리 파일을 처리할 때 발생하는 문제바이너리 파일을 처리할 때 다음 방법을 사용해야 합니다.
binfile=open(filepath,'rb') #读二进制文件 binfile=open(filepath,'wb') #写二进制文件그래서 binfile=open(filepath,'r') 결과의 차이점은 무엇입니까? 두 가지 차이점이 있습니다:
먼저 'r' 사용시 '0x1A'를 만나면 파일의 끝, 즉 EOF로 간주됩니다. 'rb'를 사용하면 이 문제가 발생하지 않습니다. 즉, 바이너리로 쓰고 텍스트로 읽는 경우 '0X1A'가 있으면 파일의 일부만 읽혀지게 됩니다. 'rb'를 사용하면 파일 끝까지 읽습니다.
두 번째, 문자열 x='abcndef'에 대해 len(x)를 사용하여 길이를 7로 만들 수 있습니다. n을 개행 문자라고 부르는데 실제로는 '0X0A'입니다. 텍스트 모드인 'w'로 쓰면 '0X0A'는 윈도우 플랫폼에서는 자동으로 '0X0D', '0X0A'라는 두 글자로 변경된다. 즉, 실제로 파일 길이는 8이 된다. 'r' 텍스트 모드로 읽으면 자동으로 원래 개행 문자로 변환됩니다. 쓰기 위해 'wb' 바이너리 모드로 변경하면 한 문자는 그대로 유지되며, 읽을 때 그대로 읽혀지게 됩니다. 따라서 텍스트 모드로 쓰고 바이너리 모드로 읽는 경우 이 추가 바이트를 고려해야 합니다. '0X0D'는 캐리지 리턴 문자라고도 합니다. Linux에서는 변경되지 않습니다. 리눅스는 줄바꿈을 표현하기 위해 '0X0A'만을 사용하기 때문입니다.
위 내용은 Python의 pack 및 unpack 사용법 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!