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

Tất cả các tệp đều là nhị phân về mặt kỹ thuật, nghĩa là chúng được tạo thành từ một loạt các số 0 và 1. Tuy nhiên, khi chúng tôi đọc tệp ban đầu, chúng tôi đọc 8 bit hoặc 8 số 0 và 1 liên tiếp tại một thời điểm. 8 bit được gọi là byte và tệp văn bản lưu trữ một ký tự trong một byte. Vì vậy, nếu tôi có tệp văn bản 30 byte, điều đó có nghĩa là tệp chứa 30 ký tự

Khi chúng ta nói về các tệp nhị phân trong ngữ cảnh của bài giảng này, chúng ta đang nói về các tệp không tuân theo định dạng 1 byte, 1 ký tự. Thay vào đó, chúng tôi có định dạng tệp, chẳng hạn như tệp JPEG hoặc MP3. Chúng có định dạng mà các kỹ sư đã thiết kế. Ví dụ: JPEG phải có chiều rộng, chiều cao và danh sách các màu pixel để hiển thị hình ảnh. Có nhiều thứ khác đi vào tệp JPEG, nhưng tôi nghĩ bạn đã hiểu

Cấu trúc tệp nhị phân

Như tôi đã đề cập ở trên, các tệp nhị phân chỉ là các chuỗi 0 và 1. Không có cấu trúc vốn có. Ví dụ: nếu tôi đổi tên tệp JPEG của mình thành tệp TEXT, Windows sẽ cố mở tệp đó dưới dạng tệp văn bản. Điều này là do Windows chỉ nhìn thấy các số 0 và 1, nhưng phần mở rộng [. jpg] yêu cầu Windows mở nó dưới dạng JPEG. Nếu Windows biết điều này, nó có thể chạy một chương trình được thiết kế đặc biệt để đặt một thứ tự nhất định cho tệp JPEG

Ví dụ tệp nhị phân

Một ví dụ mà tôi thường sử dụng để chỉ ra cách hoạt động của tệp nhị phân là tệp bitmap. Đây là các tệp ảnh, giống như các tệp JPEG, nhưng không có giải nén phức tạp

Nhớ lại rằng một byte là 8 bit, là 8 số 0 và 1 ghép lại với nhau. Nói chung, nhưng không may là không phải lúc nào cũng vậy, các tệp nhị phân đơn vị địa chỉ nhỏ nhất sử dụng là một byte

Sau đây là những gì được gọi là tiêu đề, là cấu trúc được đặt thành 0 và 1 để chúng tôi biết những số 0 và 1 đó có nghĩa là gì. Đây là cấu trúc tiêu đề tệp bitmap

type [16 bits, 2 bytes]
size [32 bits, 4 bytes]
reserved [32 bits, 4 bytes]
offset [32 bits, 4 bytes]

Bạn có thể thấy ở trên rằng tất cả các kích thước không giống nhau. Vì vậy, trong tiêu đề tệp, chúng ta có thể biết đây là loại tệp bitmap nào bằng cách xem 16 số 0 và 1 mà tệp bắt đầu bằng

Đọc tập tin nhị phân

Chúng tôi có thể đọc các tệp nhị phân bằng cách thêm b vào chế độ được cung cấp để mở. Nhớ lại rằng chúng ta có thể mở một tệp, chẳng hạn như

value = int[10].to_bytes[length=4, byteorder='little']
print[type[value]]
1. Trong trường hợp này, nó tìm kiếm myfile. txt và mở nó ra để đọc, đó là cái mà “r” dành cho. Khi chúng tôi đọc từ tệp, Python sẽ cung cấp cho chúng tôi các chuỗi vì nó nghĩ đây là tệp văn bản. Nhớ lại rằng một chuỗi chỉ là một dãy các ký tự

Nếu chúng ta muốn mở tệp dưới dạng một chuỗi các số 0 và 1 [nhị phân] thay vì một chuỗi ký tự [văn bản], chúng ta có thể thêm một “b” vào chế độ, viết tắt của nhị phân. Ví dụ,

value = int[10].to_bytes[length=4, byteorder='little']
print[type[value]]
2 sẽ mở tệp myfile. bin để đọc dưới dạng tệp nhị phân. Bây giờ chúng ta đã thêm “b”, Python sẽ cung cấp cho chúng ta kiểu dữ liệu byte thay vì chuỗi

Kiểu dữ liệu byte

Vì chúng tôi đang làm việc với byte chứ không phải chuỗi, nên Python đã thêm kiểu dữ liệu byte. Đây không phải là trường hợp trong các phiên bản Python cũ hơn, nhưng giờ đây kiểu dữ liệu này giúp việc đọc và ghi byte từ và đến một tệp dễ dàng hơn nhiều

Byte có thể được tạo bằng cách sử dụng một ký tự, trông giống như một chuỗi, nhưng nó bắt đầu bằng b, chẳng hạn như.

value = int[10].to_bytes[length=4, byteorder='little']
print[type[value]]
3. Mặc dù nó trông giống như một chuỗi, nhưng khi chúng ta gán chuỗi này cho một biến, đây sẽ là kiểu dữ liệu byte. Hãy nhớ rằng khi chúng ta cắt một chuỗi, chẳng hạn như
value = int[10].to_bytes[length=4, byteorder='little']
print[type[value]]
0 hoặc
value = int[10].to_bytes[length=4, byteorder='little']
print[type[value]]
1, chúng ta sẽ nhận được một ký tự hoặc chuỗi ký tự. Giống như thế này, chúng ta nhận được một byte đơn [8 bit] hoặc chuỗi byte

Nhận byte từ số

Các số nhị phân có thể được biểu diễn bằng một chuỗi các bit. Tuy nhiên, độ dài của nó hơi tùy ý. Ví dụ: 00000000023 là 23 cũng như 023 là 23. Tuy nhiên, nếu tôi chỉ có hai chữ số, tôi không thể đại diện cho 123. Vì vậy, tôi nói "tùy ý" bởi vì chúng ta có thể sử dụng nhiều chữ số hơn mức cần thiết, nhưng không ít hơn. Đây là lý do tại sao Python cho phép chúng ta chuyển đổi một số nguyên thành một chuỗi byte, nhưng để làm như vậy, chúng ta cần cung cấp cho nó một số tham số

Khi chúng ta có một đối tượng số nguyên [có nghĩa KHÔNG phải là chữ], chúng ta có thể gọi một hàm thành viên có tên là

value = int[10].to_bytes[length=4, byteorder='little']
print[type[value]]
2 để chuyển đổi nó thành một chuỗi byte. Tuy nhiên, hãy nhớ những gì tôi đã nói, chúng ta cần cung cấp cho nó một số tham số, cụ thể là hai. kích thước và tuổi thọ

Kích thước

Hầu hết các chuỗi byte trong máy tính đều có lũy thừa là 2. 1, 2, 4 hoặc 8 byte. Số byte chính xác cho mỗi trường tùy thuộc vào cấu trúc tệp mà bạn cần biết trước khi ghi hoặc đọc từ đó

độ bền

Endianness không khó hiểu đến thế, nhưng nó khác với những gì chúng ta đã nói trước đây. Endianness có nghĩa là phần cuối của số nào sẽ đến trước. Nó có hai hương vị. lớn hay nhỏ, nghĩa là chúng ta lưu đầu nhỏ [các chữ số ngoài cùng bên phải] trước hay đầu lớn [các chữ số ngoài cùng bên trái]. Hình dưới đây cho thấy có hai cách chúng ta có thể lưu trữ một số. lớn hay nhỏ

Ví dụ về đơn đặt hàng byte cuối lớn và nhỏ

Con người đọc bằng big-endian nếu bạn đọc từ trái sang phải. Bạn có thể thấy rằng số chúng tôi đang lưu trữ là 1a_2b_3c_4d_5e_6f_70_80. Đây là số cơ số 16 [thập lục phân]. Tuy nhiên, trong little endian, nó được lưu ngược lại, vì đầu nhỏ [byte ngoài cùng bên phải] được lưu trước

Chuyển đổi số nguyên thành byte

Một lần nữa, chúng ta có thể sử dụng to_bytes để tạo một chuỗi byte. Ví dụ

value = int[10].to_bytes[length=4, byteorder='little']
print[type[value]]

Trong đoạn mã trên, chúng tôi bắt buộc phải sử dụng int[10] vì hàm to_bytes hoạt động trên một đối tượng số nguyên chứ không phải số nguyên. Cũng giống như mọi thứ khác trong Python, có vô số cách để thực hiện thao tác này, tuy nhiên, tôi thấy cách này là dễ nhất

Có hai tham số bắt buộc đối với to_bytes, độ dài, là số byte và thứ tự byte, xác định xem phần này sẽ được lưu trữ đầu nhỏ hay đầu lớn trước. Tham số byteorder lấy một chuỗi là 'lớn' hoặc 'nhỏ'

Khi chúng ta in kiểu biến mà chúng ta lấy lại, nó sẽ in như sau

Vì vậy, chúng ta có một lớp byte một cách hợp pháp, chứa hàm to_bytes[] của chúng ta. Chúng tôi có thể ghi vào một tệp bằng cách sử dụng cùng một thao tác ghi, ngoại trừ bây giờ chúng tôi chuyển nó bytes[]. Ví dụ,

i = 100
j = 200
k = 0xdeadbeef
i_bytes = i.to_bytes[length=1, byteorder='little']
j_bytes = j.to_bytes[length=2, byteorder='little']
k_bytes = k.to_bytes[length=4, byteorder='little']
f = open["myfile.bin", "wb"]
f.write[i_bytes]
f.write[j_bytes]
f.write[k_bytes]
f.close[]

Lưu ý rằng khi tôi viết, số byte để ghi vào tệp đến từ biến XX_bytes chứ không phải chính hàm ghi. Trong trường hợp này, chúng ta có thể chuyển đổi số nguyên thành byte bằng cách sử dụng to_bytes. Chúng tôi có thể chỉ định bao nhiêu byte chúng tôi muốn bằng cách chỉ định độ dài

Nếu bạn cố gắng chuyển đổi thành_bytes bằng cách sử dụng độ dài mà số nguyên không vừa, Python sẽ đưa ra lỗi OverflowError như bạn có thể thấy bên dưới

>>> int[2000].to_bytes[length=1, byteorder='little']
Traceback [most recent call last]:
  File "", line 1, in 
OverflowError: int too big to convert

Khi tôi chỉ định độ dài = 1, tôi đang nói với to_bytes rằng tôi muốn số nguyên vừa với một byte. Tuy nhiên, một byte [8 bit] sẽ đạt tối đa \[2^{8}-1=255\]. Điều này không chính xác 100% trong máy tính, nhưng tôi không muốn làm phức tạp mọi thứ. Khi chúng tôi lưu trữ các số âm, chúng tôi sử dụng một chút để lưu trữ dấu hiệu, vì vậy nó không hoàn toàn như thế này. Tuy nhiên, tôi chỉ đưa ra ví dụ này để cho thấy rằng có vấn đề khi chúng tôi lưu trữ các số lớn với độ dài nhỏ hơn

Từ byte

Phần trước đã hướng dẫn cách chuyển đổi từ kiểu số nguyên sang kiểu dữ liệu byte. Tuy nhiên, điều này thực sự chỉ hữu ích khi chúng ta viết byte. Điều gì xảy ra khi chúng ta muốn đọc byte từ tệp nhị phân?

f = open["myfile.bin", "rb"]
four_bytes = f.read[4]
two_bytes = f.read[2]
one_byte = f.read[1]
f.close[]
print["Four bytes is:", int.from_bytes[four_bytes, byteorder='little']]
print["Two bytes is:", int.from_bytes[two_bytes, byteorder='little']]
print["One byte is:", int.from_bytes[one_byte, byteorder='little']]

Bạn có thể thấy ở trên, chúng ta phải chỉ định byteorder một lần nữa khi chuyển đổi từ byte thành số nguyên. Chúng tôi không chỉ định độ dài vì chúng tôi biết độ dài từ chính đối tượng byte

Mảng byte

Một đối tượng bytes là bất biến, có nghĩa là chúng ta không thể sửa đổi nó tại chỗ, giống như một bộ dữ liệu. Chúng ta có thể tạo một đối tượng bytes mới để thực hiện một số phép biến đổi, nhưng nếu chúng ta chỉ muốn thay đổi một phần của đối tượng bytes thì sao? . Các đối tượng này rất giống với các đối tượng byte, tuy nhiên chúng có thể được thay đổi tại chỗ, giống như một danh sách

Chúng ta có thể thay đổi đối tượng bytes thành đối tượng bytearray bằng cách sử dụng bytearray[bytes_object] và ngược lại

value = int[10].to_bytes[length=4, byteorder='little']
print[type[value]]
0

Đoạn mã trên lấy một đối tượng bytes, sao chép nó vào một mảng byte, thay đổi 's' thành 'z' và sao chép lại. Lưu ý rằng tôi phải sử dụng ord[“z”], đây là một hàm đặc biệt cung cấp cho tôi biểu diễn số nguyên của chữ thường z

GHI CHÚ. Đọc và ghi vào tệp nhị phân sử dụng đối tượng byte bất biến. Tuy nhiên, như bạn có thể thấy ở trên, bạn có thể chuyển đổi sang và từ

Làm cách nào để chuyển đổi chuỗi thành nhị phân trong Python?

Để chuyển đổi một chuỗi thành nhị phân, trước tiên chúng ta nối các giá trị ASCII riêng lẻ của chuỗi vào một danh sách [ l ] bằng cách sử dụng hàm ord[_string]. This function gives the ASCII value of the string [i.e., ord[H] = 72 , ord[e] = 101]. Then, from the list of ASCII values we can convert them to binary using bin[_integer] .

Chúng ta có thể mở tệp văn bản ở chế độ nhị phân không?

Khoa học dữ liệu thực tế sử dụng Python . Để mở tệp ở chế độ nhị phân, khi chỉ định một chế độ, hãy thêm 'b' vào đó .

Là. Tệp PY là tệp nhị phân?

Python có các công cụ để làm việc với tệp nhị phân . Các tệp nhị phân sử dụng các chuỗi kiểu byte. Điều này có nghĩa là khi đọc dữ liệu nhị phân từ một tệp, một đối tượng kiểu byte được trả về. Tệp nhị phân được mở bằng hàm open[], có tham số chế độ chứa ký tự 'b'.

Chủ Đề