Giải nén tệp nhị phân Python

Giả sử bạn cần đọc một tệp nhị phân chứa dữ liệu về các khu vực đô thị, được tạo bởi một chương trình trong C với một bản ghi được định nghĩa là

ví dụ 1. Khu vực tàu điện ngầm. cấu trúc trong ngôn ngữ C

struct MetroArea {
    int year;
    char name[12];
    char country[2];
    float population;
};

Đây là cách đọc một bản ghi ở định dạng đó, sử dụng struct.unpack

ví dụ 2. Đọc cấu trúc C trong bảng điều khiển Python

>>> from struct import unpack, calcsize
>>> FORMAT = 'i12s2sf'
>>> size = calcsize[FORMAT]
>>> data = open['metro_areas.bin', 'rb'].read[size]
>>> data
b"\xe2\x07\x00\x00Tokyo\x00\xc5\x05\x01\x00\x00\x00JP\x00\x00\x11X'L"
>>> unpack[FORMAT, data]
[2018, b'Tokyo\x00\xc5\x05\x01\x00\x00\x00', b'JP', 43868228.0]

Lưu ý cách unpack trả về một bộ có bốn trường, như được chỉ định bởi chuỗi FORMAT. Các chữ cái và số trong FORMAT được mô tả trong tài liệu mô-đun struct

Bảng 1. Các phần của chuỗi định dạng 'i12s2sf'. partizeC typePython giới hạn cho nội dung thực tế

>>> from struct import unpack, calcsize
>>> FORMAT = 'i12s2sf'
>>> size = calcsize[FORMAT]
>>> data = open['metro_areas.bin', 'rb'].read[size]
>>> data
b"\xe2\x07\x00\x00Tokyo\x00\xc5\x05\x01\x00\x00\x00JP\x00\x00\x11X'L"
>>> unpack[FORMAT, data]
[2018, b'Tokyo\x00\xc5\x05\x01\x00\x00\x00', b'JP', 43868228.0]
0

4 byte

>>> from struct import unpack, calcsize
>>> FORMAT = 'i12s2sf'
>>> size = calcsize[FORMAT]
>>> data = open['metro_areas.bin', 'rb'].read[size]
>>> data
b"\xe2\x07\x00\x00Tokyo\x00\xc5\x05\x01\x00\x00\x00JP\x00\x00\x11X'L"
>>> unpack[FORMAT, data]
[2018, b'Tokyo\x00\xc5\x05\x01\x00\x00\x00', b'JP', 43868228.0]
1

>>> from struct import unpack, calcsize
>>> FORMAT = 'i12s2sf'
>>> size = calcsize[FORMAT]
>>> data = open['metro_areas.bin', 'rb'].read[size]
>>> data
b"\xe2\x07\x00\x00Tokyo\x00\xc5\x05\x01\x00\x00\x00JP\x00\x00\x11X'L"
>>> unpack[FORMAT, data]
[2018, b'Tokyo\x00\xc5\x05\x01\x00\x00\x00', b'JP', 43868228.0]
1

32 bit;

>>> from struct import unpack, calcsize
>>> FORMAT = 'i12s2sf'
>>> size = calcsize[FORMAT]
>>> data = open['metro_areas.bin', 'rb'].read[size]
>>> data
b"\xe2\x07\x00\x00Tokyo\x00\xc5\x05\x01\x00\x00\x00JP\x00\x00\x11X'L"
>>> unpack[FORMAT, data]
[2018, b'Tokyo\x00\xc5\x05\x01\x00\x00\x00', b'JP', 43868228.0]
3

12 byte

>>> from struct import unpack, calcsize
>>> FORMAT = 'i12s2sf'
>>> size = calcsize[FORMAT]
>>> data = open['metro_areas.bin', 'rb'].read[size]
>>> data
b"\xe2\x07\x00\x00Tokyo\x00\xc5\x05\x01\x00\x00\x00JP\x00\x00\x11X'L"
>>> unpack[FORMAT, data]
[2018, b'Tokyo\x00\xc5\x05\x01\x00\x00\x00', b'JP', 43868228.0]
4

>>> from struct import unpack, calcsize
>>> FORMAT = 'i12s2sf'
>>> size = calcsize[FORMAT]
>>> data = open['metro_areas.bin', 'rb'].read[size]
>>> data
b"\xe2\x07\x00\x00Tokyo\x00\xc5\x05\x01\x00\x00\x00JP\x00\x00\x11X'L"
>>> unpack[FORMAT, data]
[2018, b'Tokyo\x00\xc5\x05\x01\x00\x00\x00', b'JP', 43868228.0]
5

chiều dài = 12

>>> from struct import unpack, calcsize
>>> FORMAT = 'i12s2sf'
>>> size = calcsize[FORMAT]
>>> data = open['metro_areas.bin', 'rb'].read[size]
>>> data
b"\xe2\x07\x00\x00Tokyo\x00\xc5\x05\x01\x00\x00\x00JP\x00\x00\x11X'L"
>>> unpack[FORMAT, data]
[2018, b'Tokyo\x00\xc5\x05\x01\x00\x00\x00', b'JP', 43868228.0]
6

2 byte

>>> from struct import unpack, calcsize
>>> FORMAT = 'i12s2sf'
>>> size = calcsize[FORMAT]
>>> data = open['metro_areas.bin', 'rb'].read[size]
>>> data
b"\xe2\x07\x00\x00Tokyo\x00\xc5\x05\x01\x00\x00\x00JP\x00\x00\x11X'L"
>>> unpack[FORMAT, data]
[2018, b'Tokyo\x00\xc5\x05\x01\x00\x00\x00', b'JP', 43868228.0]
7

>>> from struct import unpack, calcsize
>>> FORMAT = 'i12s2sf'
>>> size = calcsize[FORMAT]
>>> data = open['metro_areas.bin', 'rb'].read[size]
>>> data
b"\xe2\x07\x00\x00Tokyo\x00\xc5\x05\x01\x00\x00\x00JP\x00\x00\x11X'L"
>>> unpack[FORMAT, data]
[2018, b'Tokyo\x00\xc5\x05\x01\x00\x00\x00', b'JP', 43868228.0]
5

chiều dài = 2

>>> from struct import unpack, calcsize
>>> FORMAT = 'i12s2sf'
>>> size = calcsize[FORMAT]
>>> data = open['metro_areas.bin', 'rb'].read[size]
>>> data
b"\xe2\x07\x00\x00Tokyo\x00\xc5\x05\x01\x00\x00\x00JP\x00\x00\x11X'L"
>>> unpack[FORMAT, data]
[2018, b'Tokyo\x00\xc5\x05\x01\x00\x00\x00', b'JP', 43868228.0]
9

4 byte

$ python3 metro_read.py
2018    Tokyo, JP       43,868,228
2015    Shanghai, CN    38,700,000
2015    Jakarta, ID     31,689,592
0

$ python3 metro_read.py
2018    Tokyo, JP       43,868,228
2015    Shanghai, CN    38,700,000
2015    Jakarta, ID     31,689,592
0

32-bit; . 4×1038

Một chi tiết về bố cục của

$ python3 metro_read.py
2018    Tokyo, JP       43,868,228
2015    Shanghai, CN    38,700,000
2015    Jakarta, ID     31,689,592
2 không rõ ràng trong mã trong. kích thước không phải là sự khác biệt duy nhất giữa các trường
$ python3 metro_read.py
2018    Tokyo, JP       43,868,228
2015    Shanghai, CN    38,700,000
2015    Jakarta, ID     31,689,592
3 và
$ python3 metro_read.py
2018    Tokyo, JP       43,868,228
2015    Shanghai, CN    38,700,000
2015    Jakarta, ID     31,689,592
4. Trường
$ python3 metro_read.py
2018    Tokyo, JP       43,868,228
2015    Shanghai, CN    38,700,000
2015    Jakarta, ID     31,689,592
4 luôn chứa mã quốc gia gồm 2 chữ cái, nhưng
$ python3 metro_read.py
2018    Tokyo, JP       43,868,228
2015    Shanghai, CN    38,700,000
2015    Jakarta, ID     31,689,592
3 là một chuỗi có tận cùng bằng không có tối đa 12 byte bao gồm cả _____12_______7 kết thúc—mà bạn có thể nhìn thấy ngay sau từ
$ python3 metro_read.py
2018    Tokyo, JP       43,868,228
2015    Shanghai, CN    38,700,000
2015    Jakarta, ID     31,689,592
8

Bây giờ, hãy xem lại một kịch bản để trích xuất tất cả các bản ghi từ

$ python3 metro_read.py
2018    Tokyo, JP       43,868,228
2015    Shanghai, CN    38,700,000
2015    Jakarta, ID     31,689,592
2 và tạo một báo cáo đơn giản như thế này

$ python3 metro_read.py
2018    Tokyo, JP       43,868,228
2015    Shanghai, CN    38,700,000
2015    Jakarta, ID     31,689,592

giới thiệu chức năng

from struct import iter_unpack

FORMAT = 'i12s2sf'                             # [1]

def text[field: bytes] -> str:                 # [2]
    octets = field.split[b'\0', 1][0]          # [3]
    return octets.decode['cp437']              # [4]

with open['metro_areas.bin', 'rb'] as fp:      # [5]
    data = fp.read[]

for fields in iter_unpack[FORMAT, data]:       # [6]
    year, name, country, pop = fields
    place = text[name] + ', ' + text[country]  # [7]
    print[f'{year}\t{place}\t{pop:,.0f}']
0 tiện dụng

ví dụ 3. tàu điện ngầm. py. liệt kê tất cả các bản ghi từ

$ python3 metro_read.py
2018    Tokyo, JP       43,868,228
2015    Shanghai, CN    38,700,000
2015    Jakarta, ID     31,689,592
2

from struct import iter_unpack

FORMAT = 'i12s2sf'                             # [1]

def text[field: bytes] -> str:                 # [2]
    octets = field.split[b'\0', 1][0]          # [3]
    return octets.decode['cp437']              # [4]

with open['metro_areas.bin', 'rb'] as fp:      # [5]
    data = fp.read[]

for fields in iter_unpack[FORMAT, data]:       # [6]
    year, name, country, pop = fields
    place = text[name] + ', ' + text[country]  # [7]
    print[f'{year}\t{place}\t{pop:,.0f}']

  1. Định dạng struct

  2. Chức năng tiện ích để giải mã và dọn sạch các trường

    >>> from struct import unpack, calcsize
    >>> FORMAT = 'i12s2sf'
    >>> size = calcsize[FORMAT]
    >>> data = open['metro_areas.bin', 'rb'].read[size]
    >>> data
    b"\xe2\x07\x00\x00Tokyo\x00\xc5\x05\x01\x00\x00\x00JP\x00\x00\x11X'L"
    >>> unpack[FORMAT, data]
    [2018, b'Tokyo\x00\xc5\x05\x01\x00\x00\x00', b'JP', 43868228.0]
    5;

  3. Xử lý chuỗi C kết thúc null. tách một lần vào ngày

    $ python3 metro_read.py
    2018    Tokyo, JP       43,868,228
    2015    Shanghai, CN    38,700,000
    2015    Jakarta, ID     31,689,592
    7, sau đó lấy phần đầu tiên

  4. Giải mã

    >>> from struct import unpack, calcsize
    >>> FORMAT = 'i12s2sf'
    >>> size = calcsize[FORMAT]
    >>> data = open['metro_areas.bin', 'rb'].read[size]
    >>> data
    b"\xe2\x07\x00\x00Tokyo\x00\xc5\x05\x01\x00\x00\x00JP\x00\x00\x11X'L"
    >>> unpack[FORMAT, data]
    [2018, b'Tokyo\x00\xc5\x05\x01\x00\x00\x00', b'JP', 43868228.0]
    5 thành
    from struct import iter_unpack
    
    FORMAT = 'i12s2sf'                             # [1]
    
    def text[field: bytes] -> str:                 # [2]
        octets = field.split[b'\0', 1][0]          # [3]
        return octets.decode['cp437']              # [4]
    
    with open['metro_areas.bin', 'rb'] as fp:      # [5]
        data = fp.read[]
    
    for fields in iter_unpack[FORMAT, data]:       # [6]
        year, name, country, pop = fields
        place = text[name] + ', ' + text[country]  # [7]
        print[f'{year}\t{place}\t{pop:,.0f}']
    4

  5. Mở và đọc toàn bộ tệp ở chế độ nhị phân;

  6. struct.unpack0 trả về một trình tạo tạo ra một bộ trường cho mỗi chuỗi byte khớp với chuỗi định dạng

  7. Các trường

    $ python3 metro_read.py
    2018    Tokyo, JP       43,868,228
    2015    Shanghai, CN    38,700,000
    2015    Jakarta, ID     31,689,592
    3 và
    $ python3 metro_read.py
    2018    Tokyo, JP       43,868,228
    2015    Shanghai, CN    38,700,000
    2015    Jakarta, ID     31,689,592
    4 cần xử lý thêm bằng hàm struct.unpack3

Mô-đun struct không cung cấp cách nào để chỉ định các trường chuỗi kết thúc null. Khi xử lý một trường như

$ python3 metro_read.py
2018    Tokyo, JP       43,868,228
2015    Shanghai, CN    38,700,000
2015    Jakarta, ID     31,689,592
3 trong ví dụ trên, sau khi giải nén chúng ta cần kiểm tra các byte trả về để loại bỏ
$ python3 metro_read.py
2018    Tokyo, JP       43,868,228
2015    Shanghai, CN    38,700,000
2015    Jakarta, ID     31,689,592
7 đầu tiên và tất cả các byte sau nó trong trường đó. Rất có thể các byte sau
$ python3 metro_read.py
2018    Tokyo, JP       43,868,228
2015    Shanghai, CN    38,700,000
2015    Jakarta, ID     31,689,592
7 đầu tiên và cho đến cuối trường là rác. Bạn thực sự có thể thấy điều đó trong

Chế độ xem bộ nhớ có thể giúp thử nghiệm và gỡ lỗi chương trình bằng cách sử dụng struct dễ dàng hơn, như phần tiếp theo sẽ giải thích

Làm cách nào để trích xuất dữ liệu từ tệp nhị phân Python?

# Mở trình xử lý tệp để tạo tệp nhị phân. file=open["số_danh_sách. bin","wb"] # Khai báo danh sách các giá trị số. .
# Mở tệp nhị phân để đọc. tệp = mở ["số_danh sách. bin", "rb"] # Đọc năm số đầu tiên vào một danh sách. .
# Nhập mô-đun NumPy. nhập numpy dưới dạng np. # Khai báo mảng numpy

Làm cách nào để mở tệp nhị phân?

Để mở Binary Editor trên một tệp mới, vào menu Tệp > Mới > Tệp, chọn loại tệp bạn muốn chỉnh sửa, sau đó chọn mũi tên thả xuống bên cạnh . .

Làm cách nào để chuyển đổi nhị phân thành văn bản trong Python?

Dữ liệu nhị phân được chia thành bộ 7 bit vì bộ nhị phân này làm đầu vào, trả về giá trị thập phân tương ứng là mã ASCII của ký tự trong chuỗi. Mã ASCII này sau đó được chuyển đổi thành chuỗi bằng hàm chr[] .

Làm cách nào để đọc tệp CSV nhị phân bằng Python?

Để đọc tệp nhị phân, hãy sử dụng hàm open['rb'] trong trình quản lý ngữ cảnh [ có từ khóa] và đọc nội dung của nó thành một biến chuỗi bằng f. readlines[] . Sau đó, bạn có thể chuyển đổi chuỗi thành CSV bằng nhiều cách tiếp cận khác nhau, chẳng hạn như mô-đun csv.

Chủ Đề