Đọc ghi file nhị phân trong python 3.x

Hi HelloWorld.

  1. nếu không dùng các module import thêm thì đọc ghi bằng cách nào bạn nhỉ? Không có chuyện không dùng module. Có thành hành xác nhau.
  2. Có 2 cách. Tìm mã nguồn của nó rồi tống vào. Hoặc tự viết. Cũng không khó đọc tài liệu về chuẩn ghi byte là có thể chuyển từ byte sang kiểu giá trị được.
2 Likes

Bạn tưởng là xâu thường, nhưng thực tế thì không phải.

image

Bạn in kết quả ra file thì file chỉ hiển thị ra xâu thường, thực tế là file đó vẫn là file binary, vẫn chứa binary string.

Hình như do Notepad++ hiển thị kí tự ASCII trên file binary vẫn là chính nó chứ không phải các byte. Nếu không tin file không chứa xâu thường thì bạn đọc ngược lại và in xem nội dung file là kiểu gì, string hay binary string.

Bonus thêm cho bạn:

image

3 Likes
file_output = open("output.dat", "wb")
a = 1
file_output.write(repr(a).encode())
b = 1.2
file_output.write(b.__repr__().encode())
c = "hello"
file_output.write(repr(c).encode())
file_output.close()

mình xem thử trên notepad, vscode, notepad++ ra text cả
image
image
image

nhưng trong c/c++, ghi file nhị phân nó sẽ ntn

image

thật sự mình chưa hiểu file nhị phân trên python là ntn :crazy_face:

Quote lại cho bạn nhìn

2 Likes

mình biết là nó kiểu bytes. nhưng vấn đề là ở cái file binary ấy
sao mình thấy nó khác c/c++ vậy

File text = dữ liệu sẽ được tách từng kí tự và chuyển về mã ascii (mapping &
encoding, 8 bit = 1 byte = 1 kí tự ) có thể mở bằng trình soạn thảo văn bản để đọc,
khi mở file notepad sẽ load dữ liệu có trong file, là mã ascii nên có thể hiện thị
int x = 1297;
biến x tồn tại dưới dạng mã nhị phân và chiếm 4 byte (kiểu int) trong bộ nhớ
khi ghi vào file , x được biểu diễn thành các kí tự ‘1’, ‘2’, ‘9’, ‘7’
‘1’ có mã ascii 000 0001
‘2’ có mã ascii 000 0010
‘9’ có mã ascii 000 1001
‘7’ có mã ascii 000 0111
Các biểu diễn ascii này được ghi vào file text  có thể mở và đọc được
quá trình đọc file tương tự, đọc mã ascii rồi mapping thành dữ liệu ở mã nhị
phân, để lưu trữ trong bộ nhớ

File binary = dữ liệu ở dạng thô chưa được mã hóa, đọc ghi theo byte, không thể
mở bằng trình soạn thảo và đọc như file text (trừ kí tự, vì kí tự có thể hiển thị
được với mã ascii)
int x = 1297;
biến x tồn tại dưới dạng mã nhị phân và chiếm 4 byte (kiểu int) trong bộ nhớ
khi ghi vào file, x sẽ được chuyển về hệ nhị phân = 10100010001
dữ liệu sẽ được ghi dưới dạng thô này và không được mã hóa, ghi theo byte (
1byte = 8bit)
quá trình đọc tương tự, đọc theo byte

Dùng built-in bytearray() xem.

2 Likes

bytearray trả về 1 mảng bytes với n phần tử hoặc xâu cho trước

file_output = open("output.dat", "wb")
data = bytearray(1.3) # error, chả lẽ lại str(1.3) :smile: . Tương tự bytes, chỉ là cái bytes này immutable, còn bytearray thì mutable
file_output.write(data)

TypeError: ‘float’ object is not iterable

Bạn đang dùng sai rồi.

image

2 Likes

Theo mình biết là dùng ntn

data = bytes(5)
print(data)

data = bytes("123 abc @#$", 'utf-8')
print(data)

data = bytearray(5)
print(data)
data[0] = 1
print(data)

data = bytearray("123 abc @#$", 'utf-8')
print(data)

nhưng mục tiêu là ghi số 1.3 vào file nhị phân mà

chả lẽ ntn

a = 1.3
data = bytearray(repr(a), 'utf-8')

vẫn ra
image

sorry bạn, post bài mà để bạn sửa cho nhiều quá :smile: tks

Thôi chắc mình dùng đại 1 cách nào đó vậy
Mà bình thường bạn ghi

a = 1
b= 1.3 
c= "hello" 

vào file nhị phân bạn ghi ntn?
Mình qua phần file bên python thấy khác bên c/c++ quá :smile:
C/C++ tuy dài dòng nhưng kiểm soát tốt hơn

Mình cũng không có nhu cầu in số ra file binary lắm, toàn in xâu nên cũng không để ý gì nhiều, toàn in trực tiếp bằng file.write(...).

Xem qua thì thấy dùng struct có vẻ vẫn tối ưu.

2 Likes

Như này error mà

file_output = open("output.dat", "wb")
file_output.write("hello")

TypeError: a bytes-like object is required, not 'str'

Mình xem thấy nhiều cách lắm:

  • b"something string"
  • encode, decode, repr
  • bytes, bytearray

Còn import thêm thì có

  • struct
  • pickle

Nhưng mở ra toàn thấy text luôn, cảm giác như nó mapping r. Là file văn bản, nhưng đọc lên check type thì lại là bytes

Hi.

  1. Muốn check file nhị phân hay văn bản thì kiểm tra dung lượng của nó.
    VD: Ghi 1 số float xuống thì nó 4 byte. Nếu nó ghi thành sâu thì size nó phụ thuộc vào số chứ số. 10 chữ số thì nó thành 10byte, Ghi một mảng tấm 100 phần tử là rõ.
  2. Bạn có thể dùng numpy save aray
    https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.save.html
  3. Nghe như quảng cáo khoa học ý.
1 Like

Em thử viết 1 đoạn code C/C++ lưu binary của 1 string/float xem sao. Cũng không khác biệt nhiều lắm đâu.

1 Like

kí tự thì bên c/c++ ghi nhị phân xong vẫn thấy, nhưng ví dụ như số 1.2 thì sẽ ra các kí tự đặc biệt, còn với những cách trên bên py thì ra rõ text 1.2 anh ơi

cách này

ghi 1.3 thì nó ghi str xuống, dung lượng là 3bytes, vì bản chất repr lấy 1 chuỗi biểu diễn được đại diên cho obj, nó tương tự str nhưng fully hơn

dùng struct thì ngon lành r, 4 bytes đàng hoàng, và mở file text lên nó cũng hiển thị kí tự đặc biệt

import struct
file_output = open("output.dat", "wb")
file_output.write(struct.pack(">f", 2.2))
file_output.close()

Ký tự nào trong CS cũng đặc biệt cả, không có ký tự nào xuất hiện trong ASCII/unicode table 2 lần.

Ý a là em thử implement 1 đoạn code bằng C/C++ lưu 1 string (“Hello world”) hay float (-1.2) dưới dạng binary, em sẽ hiểu vì sao mình không làm được nó ở Python.

1 Like

e lưu “Hello world” thì ra Hello world và 1 kí tự đặc biêt là ‘\n’ ở cuối
còn lưu -1.2 thì nó ra kí tự đặc biệt
e vẫn chưa hiểu ý a muốn truyền tải, a có thể giải thích rõ hơn k, e chưa rõ tại sao có sự khác biệt này

em dùng module struct thì vẫn ghi như bên c/c++

  • số bytes đúng, ví dụ 1.2 = 4 bytes chứ k phải 3 bytes
  • mở bằng notepad++ ra kí tự đặc biệt (1 số kí tự vẫn hiển thị thường)
  • chuyển ascii -> hex -> float thì giá trị đúng như khi ghi vào

Trong python .encode() method không dùng để chuyển sang binary code, theo manual thì str.encode() returns bytes representation of the unicode string,

In [24]: a = 'Nguyễn'

In [25]: a.encode()
Out[25]: b'Nguy\xe1\xbb\x85n'

In [26]: a.encode('utf-8')
Out[26]: b'Nguy\xe1\xbb\x85n'

cũng trong Python, bytes representation chỉ biểu diễn bảng ASCII, nghĩa là 0 <= bytes < 256 nên chữ biểu diễn dưới dạng hex thay vì str thuộc ASCII.

Đoạn sau anh không hiểu em nói gì cả, ký tự đặc biệt, rồi chuyển ascii… Mã máy thì ký tự nào cũng đặc biệt, không có ký tự nào đặc biệt hơn ký tự nào cả.

  1. Em đã thử implement trong C/C++ in ra Hello world dưới binary representation chưa?
  2. Nếu được rồi thì em dùng struct sẽ in ra thứ mà em muốn.
2 Likes

kí tự đặc biệt là mấy cái lèo nghòe k đọc được đó a :smile:
em đã hiểu rồi, tks anh
image

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?