Hướng dẫn python unpack file - tệp giải nén python

Tôi có một tệp nhị phân chứa một cột của các giá trị. Sử dụng Python 3, tôi đang cố gắng giải nén dữ liệu vào một mảng hoặc danh sách.

Nội phân chính

  • Không phải là câu trả lời bạn đang tìm kiếm? Duyệt các câu hỏi khác được gắn thẻ Python Python-3.x nhị phân Giải nén hoặc đặt câu hỏi của riêng bạn.
  • Chức năng và ngoại lệ
  • Định dạng chuỗi
  • Thứ tự byte, kích thước và căn chỉnh
  • Định dạng ký tự lor
  • Làm cách nào để đọc một tệp nhị phân trong Python?
  • Cấu trúc giải nén làm gì trong Python?
  • Làm cách nào để giải nén một tệp nhị phân?
  • Làm thế nào để bạn đọc một tệp nhị phân và chuyển đổi nó thành văn bản trong Python?

file = open('data_ch04.dat', 'rb')

values = struct.unpack('f', file.read(4))[0]

print(values)

file.close()

Mã trên chỉ in một giá trị cho bảng điều khiển:

-1.1134038740480121e-29

Làm thế nào tôi có thể nhận được tất cả các giá trị từ tệp nhị phân?

Dưới đây là liên kết đến tệp nhị phân trên Dropbox:

https://www.dropbox.com/s/l69rhlrr9u0p4cq/data_ch04.dat?dl=0

Đã hỏi ngày 19 tháng 11 năm 2015 lúc 21:40Nov 19, 2015 at 21:40

Hướng dẫn python unpack file - tệp giải nén python

Mã của bạn chỉ hiển thị một float vì nó chỉ đọc bốn byte.

Thử cái này:

import struct

# Read all of the data
with open('data_ch04.dat', 'rb') as input_file:
    data = input_file.read()

# Convert to list of floats
format = '{:d}f'.format(len(data)//4)
data = struct.unpack(format, data)

# Display some of the data
print len(data), "entries"
print data[0], data[1], data[2], "..."

Đã trả lời ngày 19 tháng 11 năm 2015 lúc 21:54Nov 19, 2015 at 21:54

RobᵩrobᵩRobᵩ

157K17 Huy hiệu vàng224 Huy hiệu bạc300 Huy hiệu Đồng17 gold badges224 silver badges300 bronze badges

3

Không phải là câu trả lời bạn đang tìm kiếm? Duyệt các câu hỏi khác được gắn thẻ Python Python-3.x nhị phân Giải nén hoặc đặt câu hỏi của riêng bạn.

import os, re
import functools
import ctypes
from ctypes import string_at, byref, sizeof, cast, POINTER, pointer, create_string_buffer, memmove
import numpy as np
import pandas as pd

class _StructBase(ctypes.Structure):
    __type__ = 0
    _fields_ = []

    @classmethod
    def Offsetof(cls, field):
        pattern = '(?P<field>\w+)\[(?P<idx>\d+)\]'

        mat = re.match(pattern, field)
        if mat:
            fields = dict(cls.Fields())
            f = mat.groupdict()['field']
            idx = mat.groupdict()['idx']
            return cls.Offsetof(f) + int(idx) * ctypes.sizeof(fields[field])
        else:
            return getattr(cls, field).offset

    @classmethod
    def DType(cls):
        map = {
            ctypes.c_byte: np.byte,
            ctypes.c_ubyte: np.ubyte,
            ctypes.c_char: np.ubyte,

            ctypes.c_int8: np.int8,
            ctypes.c_int16: np.int16,
            ctypes.c_int32: np.int32,
            ctypes.c_int64: np.int64,

            ctypes.c_uint8: np.uint8,
            ctypes.c_uint16: np.uint16,
            ctypes.c_uint32: np.uint32,
            ctypes.c_uint64: np.uint64,

            ctypes.c_float: np.float32,
            ctypes.c_double: np.float64,
        }
        res = []

        for k, v in cls.Fields():
            if hasattr(v, '_length_'):
                if v._type_ != ctypes.c_char:
                    for i in range(v._length):
                        res.append((k, map[v], cls.Offsetof(k)))
                else:
                    res.append((k, 'S%d' % v._length_, cls.Offsetof(k)))
            else:
                res.append((k, map[v], cls.Offsetof(k)))
        res = pd.DataFrame(res, columns=['name', 'format', 'offset'])
        return np.dtype({
            'names': res['name'],
            'formats': res['format'],
            'offsets': res['offset'],
        })

    @classmethod
    def Attr(cls):
        fields = cls._fields_
        res = []
        for attr, tp in fields:
            if str(tp).find('_Array_') > 0 and str(tp).find('char_Array_') < 0:
                for i in range(tp._length_):
                    res.append((attr + '[%s]' % str(i), tp._type_))
            else:
                res.append((attr, tp))
        return res

    @classmethod
    def Fields(cls, notype=False):
        res = [cls.Attr()]
        cur_cls = cls
        while True:
            cur_cls = cur_cls.__bases__[0]
            if cur_cls == ctypes.Structure:
                break
            res.append(cur_cls.Attr())
        if notype:
            return [k for k, v in functools.reduce(list.__add__, reversed(res), [])]
        else:
            return functools.reduce(list.__add__, reversed(res), [])

    @classmethod
    def size(cls):
        return sizeof(cls)

    @classmethod
    def from_struct_binary(cls, path, max_count=2 ** 32, decode=True):
        print(os.path.getsize(path), cls.size())
        assert os.path.getsize(path) % cls.size() == 0
        size = os.path.getsize(path) // cls.size()
        size = min(size, max_count)

        index = range(size)
        array = np.fromfile(path, dtype=cls.DType(), count=size)

        df = pd.DataFrame(array, index=index)
        for attr, tp in eval(str(cls.DType())):
            if re.match('S\d+', tp) is not None and decode:
                try:
                    df[attr] = df[attr].map(lambda x: x.decode("utf-8"))
                except:
                    df[attr] = df[attr].map(lambda x: x.decode("gbk"))
        return df

class StructBase(_StructBase):
    _fields_ = [
        ('Type', ctypes.c_uint32),
    ]

class IndexStruct(StructBase):
    _fields_ = [
        ('Seq', ctypes.c_uint32),
        ('ExID', ctypes.c_char * 8),
        ('SecID', ctypes.c_char * 8),
        ('SecName', ctypes.c_char * 16),
        ('SourceID', ctypes.c_int32),
        ('Time', ctypes.c_uint32),
        ('PreClose', ctypes.c_uint32),
        ('Open', ctypes.c_uint32),
        ('High', ctypes.c_uint32),
        ('Low', ctypes.c_uint32),
        ('Match', ctypes.c_uint32),
    ]

df = IndexStruct.from_struct_binary('your path')
print(df)

Nội phân chính

  • Chức năng và ngoại lệ
  • Định dạng chuỗi
  • Thứ tự byte, kích thước và căn chỉnh
  • Định dạng ký tự lor
  • Làm cách nào để đọc một tệp nhị phân trong Python?
  • Cấu trúc giải nén làm gì trong Python?
  • Làm cách nào để giải nén một tệp nhị phân?
  • Làm thế nào để bạn đọc một tệp nhị phân và chuyển đổi nó thành văn bản trong Python?

Mã trên chỉ in một giá trị cho bảng điều khiển: Lib/struct.py


Làm thế nào tôi có thể nhận được tất cả các giá trị từ tệp nhị phân?Format Strings as compact descriptions of the layout of the C structs and the intended conversion to/from Python values.

Dưới đây là liên kết đến tệp nhị phân trên Dropbox:

Đã hỏi ngày 19 tháng 11 năm 2015 lúc 21:40Byte Order, Size, and Alignment for details.

Mã của bạn chỉ hiển thị một float vì nó chỉ đọc bốn byte.Buffer Protocol and provide either a readable or read-writable buffer. The most common types used for that purpose are bytes and

-1.1134038740480121e-29
5, but many other types that can be viewed as an array of bytes implement the buffer protocol, so that they can be read/filled without additional copying from a bytes object.

Chức năng và ngoại lệ

Thử cái này:

Đã trả lời ngày 19 tháng 11 năm 2015 lúc 21:54

Robᵩrobᵩ

157K17 Huy hiệu vàng224 Huy hiệu bạc300 Huy hiệu Đồng(format, v1, v2, ...)

Mã nguồn: lib/struct.py

Mô -đun này thực hiện chuyển đổi giữa các giá trị python và các cấu trúc C được biểu thị dưới dạng các đối tượng Python bytes. Điều này có thể được sử dụng để xử lý dữ liệu nhị phân được lưu trữ trong các tệp hoặc từ các kết nối mạng, trong số các nguồn khác. Nó sử dụng các chuỗi định dạng làm mô tả nhỏ gọn về bố cục của các cấu trúc C và chuyển đổi dự định sang/từ các giá trị python.(format, buffer, offset, v1, v2, ...)

Ghi chú

Theo mặc định, kết quả của việc đóng gói một cấu trúc C đã cho bao gồm các byte pad để duy trì sự liên kết thích hợp cho các loại C liên quan; Tương tự, căn chỉnh được tính đến khi giải nén. Hành vi này được chọn sao cho các byte của một cấu trúc được đóng gói tương ứng chính xác với bố cục trong bộ nhớ của cấu trúc c tương ứng. Để xử lý các định dạng dữ liệu độc lập với nền tảng hoặc bỏ qua các byte pad ngầm, hãy sử dụng kích thước và căn chỉnh ____10 thay vì kích thước và căn chỉnh
-1.1134038740480121e-29
1: Xem thứ tự byte, kích thước và căn chỉnh để biết chi tiết.(format, buffer)

Một số hàm

-1.1134038740480121e-29
2 (và các phương pháp của
-1.1134038740480121e-29
3) có đối số bộ đệm. Điều này đề cập đến các đối tượng thực hiện giao thức bộ đệm và cung cấp bộ đệm có thể đọc được hoặc dễ đọc. Các loại phổ biến nhất được sử dụng cho mục đích đó là bytes
-1.1134038740480121e-29
5, nhưng nhiều loại khác có thể được xem như một mảng byte thực hiện giao thức bộ đệm, để chúng có thể được đọc/điền mà không cần sao chép thêm từ đối tượng bytes.

Mô -đun xác định ngoại lệ và chức năng sau:(format, /, buffer, offset=0)

Ngoại lệ ________ 17 ________ 18¶

Ngoại lệ được nâng lên trong các dịp khác nhau; Đối số là một chuỗi mô tả những gì sai.(format, buffer)

________ 17 ________ 20 (Định dạng, V1, V2, ...)

Trả về một đối tượng byte chứa các giá trị v1, v2, được đóng gói theo định dạng chuỗi định dạng. Các đối số phải khớp với các giá trị theo yêu cầu của định dạng chính xác.

________ 17 ________ 22 (Định dạng, bộ đệm, Offset, V1, V2, ...)

Đóng gói các giá trị v1, v2, theo định dạng chuỗi định dạng và ghi các byte được đóng gói vào bộ đệm bộ đệm có thể ghi bắt đầu ở độ lệch vị trí. Lưu ý rằng bù là một đối số bắt buộc.(format)

________ 17 ________ 24 (Định dạng, bộ đệm) ¶

Định dạng chuỗi

Chuỗi định dạng là cơ chế được sử dụng để chỉ định bố cục dự kiến ​​khi đóng gói và giải nén dữ liệu. Chúng được xây dựng từ các ký tự định dạng, chỉ định loại dữ liệu được đóng gói/giải nén. Ngoài ra, có các ký tự đặc biệt để kiểm soát thứ tự byte, kích thước và căn chỉnh.Format Characters, which specify the type of data being packed/unpacked. In addition, there are special characters for controlling the Byte Order, Size, and Alignment.

Thứ tự byte, kích thước và căn chỉnh

Theo mặc định, các loại C được biểu diễn theo định dạng gốc của máy và thứ tự byte và được căn chỉnh đúng cách bằng cách bỏ qua byte byte nếu cần thiết (theo các quy tắc được sử dụng bởi trình biên dịch C).

Ngoài ra, ký tự đầu tiên của chuỗi định dạng có thể được sử dụng để chỉ ra thứ tự byte, kích thước và sự liên kết của dữ liệu được đóng gói, theo bảng sau:

Tính cách

Đơn đặt hàng byte

Kích thước

Liên kết

import os, re
import functools
import ctypes
from ctypes import string_at, byref, sizeof, cast, POINTER, pointer, create_string_buffer, memmove
import numpy as np
import pandas as pd

class _StructBase(ctypes.Structure):
    __type__ = 0
    _fields_ = []

    @classmethod
    def Offsetof(cls, field):
        pattern = '(?P<field>\w+)\[(?P<idx>\d+)\]'

        mat = re.match(pattern, field)
        if mat:
            fields = dict(cls.Fields())
            f = mat.groupdict()['field']
            idx = mat.groupdict()['idx']
            return cls.Offsetof(f) + int(idx) * ctypes.sizeof(fields[field])
        else:
            return getattr(cls, field).offset

    @classmethod
    def DType(cls):
        map = {
            ctypes.c_byte: np.byte,
            ctypes.c_ubyte: np.ubyte,
            ctypes.c_char: np.ubyte,

            ctypes.c_int8: np.int8,
            ctypes.c_int16: np.int16,
            ctypes.c_int32: np.int32,
            ctypes.c_int64: np.int64,

            ctypes.c_uint8: np.uint8,
            ctypes.c_uint16: np.uint16,
            ctypes.c_uint32: np.uint32,
            ctypes.c_uint64: np.uint64,

            ctypes.c_float: np.float32,
            ctypes.c_double: np.float64,
        }
        res = []

        for k, v in cls.Fields():
            if hasattr(v, '_length_'):
                if v._type_ != ctypes.c_char:
                    for i in range(v._length):
                        res.append((k, map[v], cls.Offsetof(k)))
                else:
                    res.append((k, 'S%d' % v._length_, cls.Offsetof(k)))
            else:
                res.append((k, map[v], cls.Offsetof(k)))
        res = pd.DataFrame(res, columns=['name', 'format', 'offset'])
        return np.dtype({
            'names': res['name'],
            'formats': res['format'],
            'offsets': res['offset'],
        })

    @classmethod
    def Attr(cls):
        fields = cls._fields_
        res = []
        for attr, tp in fields:
            if str(tp).find('_Array_') > 0 and str(tp).find('char_Array_') < 0:
                for i in range(tp._length_):
                    res.append((attr + '[%s]' % str(i), tp._type_))
            else:
                res.append((attr, tp))
        return res

    @classmethod
    def Fields(cls, notype=False):
        res = [cls.Attr()]
        cur_cls = cls
        while True:
            cur_cls = cur_cls.__bases__[0]
            if cur_cls == ctypes.Structure:
                break
            res.append(cur_cls.Attr())
        if notype:
            return [k for k, v in functools.reduce(list.__add__, reversed(res), [])]
        else:
            return functools.reduce(list.__add__, reversed(res), [])

    @classmethod
    def size(cls):
        return sizeof(cls)

    @classmethod
    def from_struct_binary(cls, path, max_count=2 ** 32, decode=True):
        print(os.path.getsize(path), cls.size())
        assert os.path.getsize(path) % cls.size() == 0
        size = os.path.getsize(path) // cls.size()
        size = min(size, max_count)

        index = range(size)
        array = np.fromfile(path, dtype=cls.DType(), count=size)

        df = pd.DataFrame(array, index=index)
        for attr, tp in eval(str(cls.DType())):
            if re.match('S\d+', tp) is not None and decode:
                try:
                    df[attr] = df[attr].map(lambda x: x.decode("utf-8"))
                except:
                    df[attr] = df[attr].map(lambda x: x.decode("gbk"))
        return df

class StructBase(_StructBase):
    _fields_ = [
        ('Type', ctypes.c_uint32),
    ]

class IndexStruct(StructBase):
    _fields_ = [
        ('Seq', ctypes.c_uint32),
        ('ExID', ctypes.c_char * 8),
        ('SecID', ctypes.c_char * 8),
        ('SecName', ctypes.c_char * 16),
        ('SourceID', ctypes.c_int32),
        ('Time', ctypes.c_uint32),
        ('PreClose', ctypes.c_uint32),
        ('Open', ctypes.c_uint32),
        ('High', ctypes.c_uint32),
        ('Low', ctypes.c_uint32),
        ('Match', ctypes.c_uint32),
    ]

df = IndexStruct.from_struct_binary('your path')
print(df)
6

native

native

native

import os, re
import functools
import ctypes
from ctypes import string_at, byref, sizeof, cast, POINTER, pointer, create_string_buffer, memmove
import numpy as np
import pandas as pd

class _StructBase(ctypes.Structure):
    __type__ = 0
    _fields_ = []

    @classmethod
    def Offsetof(cls, field):
        pattern = '(?P<field>\w+)\[(?P<idx>\d+)\]'

        mat = re.match(pattern, field)
        if mat:
            fields = dict(cls.Fields())
            f = mat.groupdict()['field']
            idx = mat.groupdict()['idx']
            return cls.Offsetof(f) + int(idx) * ctypes.sizeof(fields[field])
        else:
            return getattr(cls, field).offset

    @classmethod
    def DType(cls):
        map = {
            ctypes.c_byte: np.byte,
            ctypes.c_ubyte: np.ubyte,
            ctypes.c_char: np.ubyte,

            ctypes.c_int8: np.int8,
            ctypes.c_int16: np.int16,
            ctypes.c_int32: np.int32,
            ctypes.c_int64: np.int64,

            ctypes.c_uint8: np.uint8,
            ctypes.c_uint16: np.uint16,
            ctypes.c_uint32: np.uint32,
            ctypes.c_uint64: np.uint64,

            ctypes.c_float: np.float32,
            ctypes.c_double: np.float64,
        }
        res = []

        for k, v in cls.Fields():
            if hasattr(v, '_length_'):
                if v._type_ != ctypes.c_char:
                    for i in range(v._length):
                        res.append((k, map[v], cls.Offsetof(k)))
                else:
                    res.append((k, 'S%d' % v._length_, cls.Offsetof(k)))
            else:
                res.append((k, map[v], cls.Offsetof(k)))
        res = pd.DataFrame(res, columns=['name', 'format', 'offset'])
        return np.dtype({
            'names': res['name'],
            'formats': res['format'],
            'offsets': res['offset'],
        })

    @classmethod
    def Attr(cls):
        fields = cls._fields_
        res = []
        for attr, tp in fields:
            if str(tp).find('_Array_') > 0 and str(tp).find('char_Array_') < 0:
                for i in range(tp._length_):
                    res.append((attr + '[%s]' % str(i), tp._type_))
            else:
                res.append((attr, tp))
        return res

    @classmethod
    def Fields(cls, notype=False):
        res = [cls.Attr()]
        cur_cls = cls
        while True:
            cur_cls = cur_cls.__bases__[0]
            if cur_cls == ctypes.Structure:
                break
            res.append(cur_cls.Attr())
        if notype:
            return [k for k, v in functools.reduce(list.__add__, reversed(res), [])]
        else:
            return functools.reduce(list.__add__, reversed(res), [])

    @classmethod
    def size(cls):
        return sizeof(cls)

    @classmethod
    def from_struct_binary(cls, path, max_count=2 ** 32, decode=True):
        print(os.path.getsize(path), cls.size())
        assert os.path.getsize(path) % cls.size() == 0
        size = os.path.getsize(path) // cls.size()
        size = min(size, max_count)

        index = range(size)
        array = np.fromfile(path, dtype=cls.DType(), count=size)

        df = pd.DataFrame(array, index=index)
        for attr, tp in eval(str(cls.DType())):
            if re.match('S\d+', tp) is not None and decode:
                try:
                    df[attr] = df[attr].map(lambda x: x.decode("utf-8"))
                except:
                    df[attr] = df[attr].map(lambda x: x.decode("gbk"))
        return df

class StructBase(_StructBase):
    _fields_ = [
        ('Type', ctypes.c_uint32),
    ]

class IndexStruct(StructBase):
    _fields_ = [
        ('Seq', ctypes.c_uint32),
        ('ExID', ctypes.c_char * 8),
        ('SecID', ctypes.c_char * 8),
        ('SecName', ctypes.c_char * 16),
        ('SourceID', ctypes.c_int32),
        ('Time', ctypes.c_uint32),
        ('PreClose', ctypes.c_uint32),
        ('Open', ctypes.c_uint32),
        ('High', ctypes.c_uint32),
        ('Low', ctypes.c_uint32),
        ('Match', ctypes.c_uint32),
    ]

df = IndexStruct.from_struct_binary('your path')
print(df)
7

native

Tiêu chuẩn

không ai

import os, re
import functools
import ctypes
from ctypes import string_at, byref, sizeof, cast, POINTER, pointer, create_string_buffer, memmove
import numpy as np
import pandas as pd

class _StructBase(ctypes.Structure):
    __type__ = 0
    _fields_ = []

    @classmethod
    def Offsetof(cls, field):
        pattern = '(?P<field>\w+)\[(?P<idx>\d+)\]'

        mat = re.match(pattern, field)
        if mat:
            fields = dict(cls.Fields())
            f = mat.groupdict()['field']
            idx = mat.groupdict()['idx']
            return cls.Offsetof(f) + int(idx) * ctypes.sizeof(fields[field])
        else:
            return getattr(cls, field).offset

    @classmethod
    def DType(cls):
        map = {
            ctypes.c_byte: np.byte,
            ctypes.c_ubyte: np.ubyte,
            ctypes.c_char: np.ubyte,

            ctypes.c_int8: np.int8,
            ctypes.c_int16: np.int16,
            ctypes.c_int32: np.int32,
            ctypes.c_int64: np.int64,

            ctypes.c_uint8: np.uint8,
            ctypes.c_uint16: np.uint16,
            ctypes.c_uint32: np.uint32,
            ctypes.c_uint64: np.uint64,

            ctypes.c_float: np.float32,
            ctypes.c_double: np.float64,
        }
        res = []

        for k, v in cls.Fields():
            if hasattr(v, '_length_'):
                if v._type_ != ctypes.c_char:
                    for i in range(v._length):
                        res.append((k, map[v], cls.Offsetof(k)))
                else:
                    res.append((k, 'S%d' % v._length_, cls.Offsetof(k)))
            else:
                res.append((k, map[v], cls.Offsetof(k)))
        res = pd.DataFrame(res, columns=['name', 'format', 'offset'])
        return np.dtype({
            'names': res['name'],
            'formats': res['format'],
            'offsets': res['offset'],
        })

    @classmethod
    def Attr(cls):
        fields = cls._fields_
        res = []
        for attr, tp in fields:
            if str(tp).find('_Array_') > 0 and str(tp).find('char_Array_') < 0:
                for i in range(tp._length_):
                    res.append((attr + '[%s]' % str(i), tp._type_))
            else:
                res.append((attr, tp))
        return res

    @classmethod
    def Fields(cls, notype=False):
        res = [cls.Attr()]
        cur_cls = cls
        while True:
            cur_cls = cur_cls.__bases__[0]
            if cur_cls == ctypes.Structure:
                break
            res.append(cur_cls.Attr())
        if notype:
            return [k for k, v in functools.reduce(list.__add__, reversed(res), [])]
        else:
            return functools.reduce(list.__add__, reversed(res), [])

    @classmethod
    def size(cls):
        return sizeof(cls)

    @classmethod
    def from_struct_binary(cls, path, max_count=2 ** 32, decode=True):
        print(os.path.getsize(path), cls.size())
        assert os.path.getsize(path) % cls.size() == 0
        size = os.path.getsize(path) // cls.size()
        size = min(size, max_count)

        index = range(size)
        array = np.fromfile(path, dtype=cls.DType(), count=size)

        df = pd.DataFrame(array, index=index)
        for attr, tp in eval(str(cls.DType())):
            if re.match('S\d+', tp) is not None and decode:
                try:
                    df[attr] = df[attr].map(lambda x: x.decode("utf-8"))
                except:
                    df[attr] = df[attr].map(lambda x: x.decode("gbk"))
        return df

class StructBase(_StructBase):
    _fields_ = [
        ('Type', ctypes.c_uint32),
    ]

class IndexStruct(StructBase):
    _fields_ = [
        ('Seq', ctypes.c_uint32),
        ('ExID', ctypes.c_char * 8),
        ('SecID', ctypes.c_char * 8),
        ('SecName', ctypes.c_char * 16),
        ('SourceID', ctypes.c_int32),
        ('Time', ctypes.c_uint32),
        ('PreClose', ctypes.c_uint32),
        ('Open', ctypes.c_uint32),
        ('High', ctypes.c_uint32),
        ('Low', ctypes.c_uint32),
        ('Match', ctypes.c_uint32),
    ]

df = IndexStruct.from_struct_binary('your path')
print(df)
8

little-endian

Tiêu chuẩn

không ai

import os, re
import functools
import ctypes
from ctypes import string_at, byref, sizeof, cast, POINTER, pointer, create_string_buffer, memmove
import numpy as np
import pandas as pd

class _StructBase(ctypes.Structure):
    __type__ = 0
    _fields_ = []

    @classmethod
    def Offsetof(cls, field):
        pattern = '(?P<field>\w+)\[(?P<idx>\d+)\]'

        mat = re.match(pattern, field)
        if mat:
            fields = dict(cls.Fields())
            f = mat.groupdict()['field']
            idx = mat.groupdict()['idx']
            return cls.Offsetof(f) + int(idx) * ctypes.sizeof(fields[field])
        else:
            return getattr(cls, field).offset

    @classmethod
    def DType(cls):
        map = {
            ctypes.c_byte: np.byte,
            ctypes.c_ubyte: np.ubyte,
            ctypes.c_char: np.ubyte,

            ctypes.c_int8: np.int8,
            ctypes.c_int16: np.int16,
            ctypes.c_int32: np.int32,
            ctypes.c_int64: np.int64,

            ctypes.c_uint8: np.uint8,
            ctypes.c_uint16: np.uint16,
            ctypes.c_uint32: np.uint32,
            ctypes.c_uint64: np.uint64,

            ctypes.c_float: np.float32,
            ctypes.c_double: np.float64,
        }
        res = []

        for k, v in cls.Fields():
            if hasattr(v, '_length_'):
                if v._type_ != ctypes.c_char:
                    for i in range(v._length):
                        res.append((k, map[v], cls.Offsetof(k)))
                else:
                    res.append((k, 'S%d' % v._length_, cls.Offsetof(k)))
            else:
                res.append((k, map[v], cls.Offsetof(k)))
        res = pd.DataFrame(res, columns=['name', 'format', 'offset'])
        return np.dtype({
            'names': res['name'],
            'formats': res['format'],
            'offsets': res['offset'],
        })

    @classmethod
    def Attr(cls):
        fields = cls._fields_
        res = []
        for attr, tp in fields:
            if str(tp).find('_Array_') > 0 and str(tp).find('char_Array_') < 0:
                for i in range(tp._length_):
                    res.append((attr + '[%s]' % str(i), tp._type_))
            else:
                res.append((attr, tp))
        return res

    @classmethod
    def Fields(cls, notype=False):
        res = [cls.Attr()]
        cur_cls = cls
        while True:
            cur_cls = cur_cls.__bases__[0]
            if cur_cls == ctypes.Structure:
                break
            res.append(cur_cls.Attr())
        if notype:
            return [k for k, v in functools.reduce(list.__add__, reversed(res), [])]
        else:
            return functools.reduce(list.__add__, reversed(res), [])

    @classmethod
    def size(cls):
        return sizeof(cls)

    @classmethod
    def from_struct_binary(cls, path, max_count=2 ** 32, decode=True):
        print(os.path.getsize(path), cls.size())
        assert os.path.getsize(path) % cls.size() == 0
        size = os.path.getsize(path) // cls.size()
        size = min(size, max_count)

        index = range(size)
        array = np.fromfile(path, dtype=cls.DType(), count=size)

        df = pd.DataFrame(array, index=index)
        for attr, tp in eval(str(cls.DType())):
            if re.match('S\d+', tp) is not None and decode:
                try:
                    df[attr] = df[attr].map(lambda x: x.decode("utf-8"))
                except:
                    df[attr] = df[attr].map(lambda x: x.decode("gbk"))
        return df

class StructBase(_StructBase):
    _fields_ = [
        ('Type', ctypes.c_uint32),
    ]

class IndexStruct(StructBase):
    _fields_ = [
        ('Seq', ctypes.c_uint32),
        ('ExID', ctypes.c_char * 8),
        ('SecID', ctypes.c_char * 8),
        ('SecName', ctypes.c_char * 16),
        ('SourceID', ctypes.c_int32),
        ('Time', ctypes.c_uint32),
        ('PreClose', ctypes.c_uint32),
        ('Open', ctypes.c_uint32),
        ('High', ctypes.c_uint32),
        ('Low', ctypes.c_uint32),
        ('Match', ctypes.c_uint32),
    ]

df = IndexStruct.from_struct_binary('your path')
print(df)
9

big-endian

Tiêu chuẩn

không ai

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

Mạng (= Big-Endian)

Tiêu chuẩn

không ai

Mạng (= Big-Endian)

Nếu nhân vật đầu tiên không phải là một trong số này,

>>> from struct import *
>>> pack('hhl', 1, 2, 3)
b'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8
1 được giả định.

Thứ tự byte bản địa là lớn hoặc ít endian, tùy thuộc vào hệ thống máy chủ. Ví dụ, Intel X86 và AMD64 (x86-64) là ít endian; IBM Z và hầu hết các kiến ​​trúc di sản là lớn; và ARM, RISC-V và IBM có tính năng chuyển mạch có thể chuyển đổi (Bi-endian, mặc dù hai người trước đây gần như luôn luôn là người thừa kế trong thực tế). Sử dụng

>>> from struct import *
>>> pack('hhl', 1, 2, 3)
b'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8
2 để kiểm tra tính endian của hệ thống của bạn.

Kích thước và căn chỉnh gốc được xác định bằng cách sử dụng biểu thức trình biên dịch C

>>> from struct import *
>>> pack('hhl', 1, 2, 3)
b'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8
3. Điều này luôn được kết hợp với thứ tự byte bản địa.Format Characters section.

Kích thước tiêu chuẩn chỉ phụ thuộc vào ký tự định dạng; Xem bảng trong phần Định dạng ký tự.

Lưu ý sự khác biệt giữa

>>> from struct import *
>>> pack('hhl', 1, 2, 3)
b'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8
1 và
>>> from struct import *
>>> pack('hhl', 1, 2, 3)
b'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8
5: Cả hai đều sử dụng thứ tự byte gốc, nhưng kích thước và sự liên kết của cái sau được tiêu chuẩn hóa.

Mẫu

>>> from struct import *
>>> pack('hhl', 1, 2, 3)
b'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8
6 đại diện cho thứ tự byte mạng luôn luôn lớn như được định nghĩa trong IETF RFC 1700.

Notes:

  1. Không có cách nào để chỉ ra thứ tự byte không bản địa (hoán đổi byte); Sử dụng lựa chọn thích hợp của

    >>> from struct import *
    >>> pack('hhl', 1, 2, 3)
    b'\x00\x01\x00\x02\x00\x00\x00\x03'
    >>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
    (1, 2, 3)
    >>> calcsize('hhl')
    8
    
    7 hoặc
    >>> from struct import *
    >>> pack('hhl', 1, 2, 3)
    b'\x00\x01\x00\x02\x00\x00\x00\x03'
    >>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
    (1, 2, 3)
    >>> calcsize('hhl')
    8
    
    8.

  2. Đadding chỉ tự động được thêm vào giữa các thành viên cấu trúc liên tiếp. Không có đệm được thêm vào ở đầu hoặc cuối của cấu trúc được mã hóa.

  3. Không có đệm được thêm vào khi sử dụng kích thước và căn chỉnh không bản địa, ví dụ: với ‘,, = =, và‘!Examples.

Để căn chỉnh phần cuối của cấu trúc với yêu cầu căn chỉnh của một loại cụ thể, hãy kết thúc định dạng bằng mã cho loại đó với số lượng lặp lại bằng không. Xem ví dụ.

Định dạng ký tự lor

Các ký tự định dạng có nghĩa sau; Việc chuyển đổi giữa các giá trị C và Python nên rõ ràng với các loại của chúng. Cột kích thước tiêu chuẩn, đề cập đến kích thước của giá trị đóng gói tính bằng byte khi sử dụng kích thước tiêu chuẩn; Đó là, khi chuỗi định dạng bắt đầu với một trong

>>> from struct import *
>>> pack('hhl', 1, 2, 3)
b'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8
7,
>>> from struct import *
>>> pack('hhl', 1, 2, 3)
b'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8
8,
>>> from struct import *
>>> pack('hhl', 1, 2, 3)
b'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8
6 hoặc
>>> from struct import *
>>> pack('hhl', 1, 2, 3)
b'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8
5. Khi sử dụng kích thước gốc, kích thước của giá trị đóng gói phụ thuộc vào nền tảng.

Định dạng

Loại c

Loại Python

Kích thước tiêu chuẩn

>>> record = b'raymond   \x32\x12\x08\x01\x08'
>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)

>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._make(unpack('<10sHHb', record))
Student(name=b'raymond   ', serialnum=4658, school=264, gradelevel=8)
3

Ghi chú

Byte pad

>>> record = b'raymond   \x32\x12\x08\x01\x08'
>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)

>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._make(unpack('<10sHHb', record))
Student(name=b'raymond   ', serialnum=4658, school=264, gradelevel=8)
4

char

Không có giá trị

1

>>> record = b'raymond   \x32\x12\x08\x01\x08'
>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)

>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._make(unpack('<10sHHb', record))
Student(name=b'raymond   ', serialnum=4658, school=264, gradelevel=8)
5

byte có độ dài 1

Đã ký char

1

Số nguyên

>>> record = b'raymond   \x32\x12\x08\x01\x08'
>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)

>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._make(unpack('<10sHHb', record))
Student(name=b'raymond   ', serialnum=4658, school=264, gradelevel=8)
6

(1), (2)

Đã ký char

1

(2)

>>> record = b'raymond   \x32\x12\x08\x01\x08'
>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)

>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._make(unpack('<10sHHb', record))
Student(name=b'raymond   ', serialnum=4658, school=264, gradelevel=8)
7

_Bool

Số nguyên

1

(1)

>>> record = b'raymond   \x32\x12\x08\x01\x08'
>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)

>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._make(unpack('<10sHHb', record))
Student(name=b'raymond   ', serialnum=4658, school=264, gradelevel=8)
8

short

Đã ký char

2

(2)

>>> record = b'raymond   \x32\x12\x08\x01\x08'
>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)

>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._make(unpack('<10sHHb', record))
Student(name=b'raymond   ', serialnum=4658, school=264, gradelevel=8)
9

Số nguyên

Đã ký char

2

(2)

>>> pack('ci', b'*', 0x12131415)
b'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, b'*')
b'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5
0

int

Đã ký char

4

(2)

>>> pack('ci', b'*', 0x12131415)
b'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, b'*')
b'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5
1

Số nguyên

Đã ký char

4

(2)

>>> pack('ci', b'*', 0x12131415)
b'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, b'*')
b'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5
2

long

Đã ký char

4

(2)

>>> pack('ci', b'*', 0x12131415)
b'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, b'*')
b'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5
3

Số nguyên

Đã ký char

4

(2)

>>> pack('ci', b'*', 0x12131415)
b'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, b'*')
b'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5
4

Số nguyên

Đã ký char

8

(2)

>>> pack('ci', b'*', 0x12131415)
b'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, b'*')
b'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5
5

Số nguyên

Đã ký char

8

(2)

>>> pack('ci', b'*', 0x12131415)
b'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, b'*')
b'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5
6

>>> pack('ci', b'*', 0x12131415)
b'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, b'*')
b'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5
7

Đã ký char

(3)

>>> pack('ci', b'*', 0x12131415)
b'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, b'*')
b'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5
8

>>> pack('ci', b'*', 0x12131415)
b'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, b'*')
b'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5
9

Đã ký char

(3)

>>> pack('llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
0

(6)

float

2

(4)

>>> pack('llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
1

float

float

4

(4)

>>> pack('llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
2

double

float

8

(4)

>>> pack('llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
3

char[]

Số nguyên

>>> pack('llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
4

char[]

Số nguyên

>>> pack('llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
5

void*

Đã ký char

(5)

Số nguyênAdded support for the

>>> pack('llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
6 and
>>> pack('llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
7 formats.

(1), (2)Added support for the

>>> pack('llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
8 format.

Notes:

  1. Char không dấu_Bool type defined by C99. If this type is not available, it is simulated using a char. In standard mode, it is always represented by one byte.

  2. bool

    không dấu ngắnAdded use of the float0 method for non-integers.

  3. Int không dấu

  4. không dấu dài

  5. Ký tự định dạng bytes1 chỉ có sẵn cho thứ tự byte gốc (được chọn là mặc định hoặc với ký tự đơn đặt hàng byte

    >>> from struct import *
    >>> pack('hhl', 1, 2, 3)
    b'\x00\x01\x00\x02\x00\x00\x00\x03'
    >>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
    (1, 2, 3)
    >>> calcsize('hhl')
    8
    
    1). Ký tự đơn đặt hàng byte
    >>> from struct import *
    >>> pack('hhl', 1, 2, 3)
    b'\x00\x01\x00\x02\x00\x00\x00\x03'
    >>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
    (1, 2, 3)
    >>> calcsize('hhl')
    8
    
    5 chọn sử dụng đơn đặt hàng ít hoặc lớn dựa trên hệ thống máy chủ. Mô -đun cấu trúc không giải thích điều này là thứ tự gốc, vì vậy định dạng bytes1 không có sẵn.

  6. Loại nhị phân của IEEE 754, một nửa chính xác đã được giới thiệu trong bản sửa đổi năm 2008 của tiêu chuẩn IEEE 754. Nó có bit dấu hiệu, số mũ 5 bit và độ chính xác 11 bit (với 10 bit được lưu trữ rõ ràng) và có thể biểu thị các số trong khoảng bytes5 và bytes6 ở độ chính xác đầy đủ. Loại này không được hỗ trợ rộng rãi bởi các trình biên dịch C: trên một máy thông thường, một ngắn không dấu có thể được sử dụng để lưu trữ, nhưng không phải cho các hoạt động toán học. Xem trang Wikipedia trên định dạng điểm nổi nửa chính xác để biết thêm thông tin.

Một ký tự định dạng có thể được đi trước bởi số lần lặp lại tích phân. Ví dụ: chuỗi định dạng bytes7 có nghĩa là giống hệt như bytes8.

Các ký tự khoảng trắng giữa các định dạng bị bỏ qua; Một số đếm và định dạng của nó không được chứa khoảng trắng mặc dù.

Đối với ký tự định dạng bytes9, số lượng được hiểu là độ dài của byte, không phải là số lượng lặp lại như đối với các ký tự định dạng khác; Ví dụ:

-1.1134038740480121e-29
00 có nghĩa là một chuỗi 10 byte duy nhất, trong khi
-1.1134038740480121e-29
01 có nghĩa là 10 ký tự. Nếu một số đếm không được đưa ra, nó mặc định là 1. Đối với việc đóng gói, chuỗi bị cắt hoặc đệm với các byte null khi thích hợp để làm cho nó phù hợp. Để giải nén, đối tượng byte kết quả luôn có chính xác số byte được chỉ định. Như một trường hợp đặc biệt,
-1.1134038740480121e-29
02 có nghĩa là một chuỗi duy nhất, trống (trong khi
-1.1134038740480121e-29
03 có nghĩa là 0 ký tự).

Khi đóng gói một giá trị

>>> record = b'raymond   \x32\x12\x08\x01\x08'
>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)

>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._make(unpack('<10sHHb', record))
Student(name=b'raymond   ', serialnum=4658, school=264, gradelevel=8)
3 sử dụng một trong các định dạng số nguyên (
-1.1134038740480121e-29
05,
-1.1134038740480121e-29
06,
-1.1134038740480121e-29
07,
-1.1134038740480121e-29
08,
-1.1134038740480121e-29
09,
-1.1134038740480121e-29
10,
-1.1134038740480121e-29
11,
-1.1134038740480121e-29
12,
-1.1134038740480121e-29
13,
-1.1134038740480121e-29
14), nếu ____.

Đã thay đổi trong phiên bản 3.1: Trước đây, một số định dạng số nguyên đã kết thúc các giá trị ngoài phạm vi và tăng

-1.1134038740480121e-29
17 thay vì
-1.1134038740480121e-29
16.Previously, some of the integer formats wrapped out-of-range values and raised
-1.1134038740480121e-29
17 instead of
-1.1134038740480121e-29
16.

Ký tự định dạng

-1.1134038740480121e-29
19 mã hóa một chuỗi pascal pascal, có nghĩa là một chuỗi có độ dài thay đổi ngắn được lưu trữ trong một số byte cố định, được đưa ra bởi số đếm. Byte đầu tiên được lưu trữ là chiều dài của chuỗi, hoặc 255, tùy theo mức nào nhỏ hơn. Các byte của chuỗi theo sau. Nếu chuỗi được truyền vào
-1.1134038740480121e-29
20 quá dài (dài hơn số đếm trừ 1), chỉ có các byte
-1.1134038740480121e-29
21 hàng đầu của chuỗi được lưu trữ. Nếu chuỗi ngắn hơn
-1.1134038740480121e-29
21, nó được đệm bằng các byte null để sử dụng chính xác các byte trong tất cả. Lưu ý rằng đối với
-1.1134038740480121e-29
23, ký tự định dạng
-1.1134038740480121e-29
19 tiêu thụ
-1.1134038740480121e-29
25 byte, nhưng chuỗi được trả về không bao giờ có thể chứa nhiều hơn 255 byte.

Đối với ký tự định dạng

>>> pack('llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
9, giá trị trả về là
-1.1134038740480121e-29
27 hoặc
-1.1134038740480121e-29
28. Khi đóng gói, giá trị sự thật của đối tượng đối số được sử dụng. 0 hoặc 1 trong biểu diễn BOOL gốc hoặc tiêu chuẩn sẽ được đóng gói và bất kỳ giá trị khác không nào sẽ là
-1.1134038740480121e-29
27 khi giải nén.

Ví dụ;

Ghi chú

Tất cả các ví dụ giả định một thứ tự byte gốc, kích thước và sự liên kết với một máy lớn.

Một ví dụ cơ bản về đóng gói/giải nén ba số nguyên:

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

Các trường được giải nén có thể được đặt tên bằng cách gán chúng cho các biến hoặc bằng cách gói kết quả trong một bộ tuple có tên:

>>> record = b'raymond   \x32\x12\x08\x01\x08'
>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)

>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._make(unpack('<10sHHb', record))
Student(name=b'raymond   ', serialnum=4658, school=264, gradelevel=8)

Đặt hàng các ký tự định dạng có thể có tác động đến kích thước vì phần đệm cần thiết để đáp ứng các yêu cầu liên kết là khác nhau:

>>> pack('ci', b'*', 0x12131415)
b'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, b'*')
b'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5

Định dạng sau

-1.1134038740480121e-29
30 chỉ định hai byte pad ở cuối, giả sử các độ dài được căn chỉnh trên các ranh giới 4 byte:

>>> pack('llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'

Điều này chỉ hoạt động khi kích thước và căn chỉnh gốc có hiệu lực; Kích thước và căn chỉnh tiêu chuẩn không thực thi bất kỳ sự liên kết nào.

Xem thêm

Mô -đun
-1.1134038740480121e-29
31

Lưu trữ nhị phân đóng gói của dữ liệu đồng nhất.

Mô -đun
-1.1134038740480121e-29
32

Đóng gói và giải nén dữ liệu XDR.

Các lớp học¶

Mô -đun

-1.1134038740480121e-29
2 cũng xác định loại sau:

Lớp ________ 17 ________ 135 (Định dạng) ¶(format)

Trả về một đối tượng cấu trúc mới ghi và đọc dữ liệu nhị phân theo định dạng chuỗi định dạng. Tạo một đối tượng struct một lần và gọi các phương thức của nó hiệu quả hơn so với việc gọi các hàm

-1.1134038740480121e-29
2 có cùng định dạng vì chuỗi định dạng chỉ cần được biên dịch một lần.

Ghi chú

Tất cả các ví dụ giả định một thứ tự byte gốc, kích thước và sự liên kết với một máy lớn.

Một ví dụ cơ bản về đóng gói/giải nén ba số nguyên:

________ 20 (v1, v2, ...)(v1, v2, ...)

Giống hệt với hàm

-1.1134038740480121e-29
20, sử dụng định dạng được biên dịch. (
-1.1134038740480121e-29
41 sẽ bằng
-1.1134038740480121e-29
42.)

________ 22 (bộ đệm, bù, v1, v2, ...) ¶(buffer, offset, v1, v2, ...)

Giống hệt với hàm

-1.1134038740480121e-29
44, sử dụng định dạng được biên dịch.

________ 24 (bộ đệm) ¶(buffer)

Giống hệt với hàm

-1.1134038740480121e-29
23, sử dụng định dạng được biên dịch. Kích thước bộ đệm trong byte phải bằng
-1.1134038740480121e-29
42.

________ 28 (bộ đệm, offset = 0) ¶(buffer, offset=0)

Giống hệt với hàm

-1.1134038740480121e-29
49, sử dụng định dạng được biên dịch. Kích thước bộ đệm trong byte, bắt đầu ở vị trí bù, phải ít nhất là
-1.1134038740480121e-29
42.

________ 31 (bộ đệm) ¶(buffer)

Giống hệt với hàm

-1.1134038740480121e-29
52, sử dụng định dạng được biên dịch. Kích thước bộ đệm trong byte phải là bội số của
-1.1134038740480121e-29
42.

Mới trong phiên bản 3.4.

________ 154¶

Chuỗi định dạng được sử dụng để xây dựng đối tượng cấu trúc này.

Đã thay đổi trong phiên bản 3.7: Loại chuỗi định dạng hiện là

-1.1134038740480121e-29
55 thay vì bytes.The format string type is now
-1.1134038740480121e-29
55 instead of bytes.

________ 157¶

Kích thước tính toán của cấu trúc (và do đó của đối tượng byte được tạo bởi phương pháp

-1.1134038740480121e-29
20) tương ứng với
-1.1134038740480121e-29
59.

Làm cách nào để đọc một tệp nhị phân trong Python?

Để mở một tệp ở định dạng nhị phân, thêm 'B' vào tham số chế độ. Do đó, chế độ "RB" mở tệp ở định dạng nhị phân để đọc, trong khi chế độ "WB" mở tệp ở định dạng nhị phân để viết. Không giống như các tệp văn bản, các tệp nhị phân không thể đọc được của con người. Khi được mở bằng bất kỳ trình soạn thảo văn bản nào, dữ liệu không thể nhận ra.add 'b' to the mode parameter. Hence the "rb" mode opens the file in binary format for reading, while the "wb" mode opens the file in binary format for writing. Unlike text files, binary files are not human-readable. When opened using any text editor, the data is unrecognizable.

Cấu trúc giải nén làm gì trong Python?

Giải nén () Hàm này chuyển đổi các chuỗi biểu diễn nhị phân thành dạng ban đầu của chúng theo định dạng được chỉ định. Loại trả về của cấu trúc.converts the strings of binary representations to their original form according to the specified format. The return type of struct.

Làm cách nào để giải nén một tệp nhị phân?

Cách giải nén A ...

Tải xuống và cài đặt một bản sao miễn phí của "Magic ISO" từ trang web Magic ISO. ....

Sau khi cài đặt, mở chương trình. ....

Sử dụng cửa sổ này để xác định vị trí và chọn tệp "cue" tương ứng với của bạn. ....

Nhấp vào biểu tượng được tô sáng để giải nén tệp bin. ....

Menu "Trích xuất cho" sẽ xuất hiện ..

Làm thế nào để bạn đọc một tệp nhị phân và chuyển đổi nó thành văn bản trong Python?

Python đọc một tập tin nhị phân cho ASCII..

Trong ví dụ này, tôi đã mở một tệp có tên Test. Bin sử dụng File = Open ('Test. ....

Tôi đã sử dụng file_encode = câu. mã hóa ('ascii'). ....

Tập tin. Seek () Phương thức trả về vị trí mới. ....

Và sau đó để chuyển đổi câu nhị phân thành ASCII, tôi đã sử dụng new_sentence = bdata. giải mã ('ascii') ..