Python 学习笔记(3)对txt文件的读与写操作(下)
? ?? ? ? ?上一章節(jié)我們討論了如何對txt文本文件進(jìn)行讀寫操作,這一張將討論如何進(jìn)行二進(jìn)制文件的寫與讀?!禤ython 學(xué)習(xí)筆記(3)對txt文件的讀與寫操作(上)》的鏈接如下https://blog.csdn.net/yanchuan23/article/details/121069465https://blog.csdn.net/yanchuan23/article/details/121069465https://blog.csdn.net/yanchuan23/article/details/121069465?????
1、uint32數(shù)據(jù)轉(zhuǎn)換為4個(gè)字節(jié)
? ? ? ? 首先看下如何將uint32轉(zhuǎn)換為4個(gè)字節(jié)。
# 計(jì)算一個(gè)無符號(hào)32位數(shù)據(jù)的bytes表達(dá) temp = [0] * 4 uintdata = 123456 for i in range(4):temp[i] = hex((uintdata >> i * 8) & 0xff)????????計(jì)算結(jié)果如下:
????????但是如果數(shù)據(jù)位浮點(diǎn)數(shù)這樣就行不通了。
????????可以用struct來解決bytes和其他二進(jìn)制數(shù)據(jù)類型的轉(zhuǎn)換。
2、 struct模塊
????????struct的作用:將字節(jié)串解讀為打包的二進(jìn)制數(shù)據(jù)。
????????該模塊執(zhí)行Python值和以Python字節(jié)對象表示的C結(jié)構(gòu)體之間的轉(zhuǎn)換。 這可以用于處理存儲(chǔ)在文件中的二進(jìn)制數(shù)據(jù)或來自其他來源的網(wǎng)絡(luò)連接的二進(jìn)制數(shù)據(jù)。 它使用格式字符串作為C結(jié)構(gòu)布局的緊湊描述,以及與Python值的轉(zhuǎn)換。
2.1、struct模塊中的功能
| 函數(shù) | return | explain | 
| pack(fmt,v1,v2…) | string | 按照給定的格式(fmt),把數(shù)據(jù)轉(zhuǎn)換成字符串(字節(jié)流),并將該字符串返回. | 
| pack_into(fmt,buffer,offset,v1,v2…) | None | 按照給定的格式(fmt),將數(shù)據(jù)轉(zhuǎn)換成字符串(字節(jié)流),并將字節(jié)流寫入以offset開始的buffer中.(buffer為可寫的緩沖區(qū),可用array模塊) | 
| unpack(fmt,v1,v2…..) | tuple | 按照給定的格式(fmt)解析字節(jié)流,并返回解析結(jié)果 | 
| pack_from(fmt,buffer,offset) | tuple | 按照給定的格式(fmt)解析以offset開始的緩沖區(qū),并返回解析結(jié)果 | 
| calcsize(fmt) | size of fmt | 計(jì)算給定的格式(fmt)占用多少字節(jié)的內(nèi)存,注意對齊方式 | 
2.2、格式化字符串
????????當(dāng)打包或者解包的時(shí),需要按照特定的方式來打包或者解包。該方式就是格式化字符串,它指定了數(shù)據(jù)類型,除此之外,還有用于控制字節(jié)順序、大小和對齊方式的特殊字符。
2.2.1、字節(jié)順序、大小與對齊方式
????????為了同c中的結(jié)構(gòu)體交換數(shù)據(jù),還要考慮c或c++編譯器使用了字節(jié)對齊,通常是以4個(gè)字節(jié)為單位,故而struct根據(jù)本地機(jī)器字節(jié)順序轉(zhuǎn)換??梢杂酶袷街械牡谝粋€(gè)字符來改變對齊方式。定義如下
| Character | Byte order (字節(jié)順序大小) | Size | Alignment(對齊) | 
| @(默認(rèn)) | 本機(jī)(native) | 本機(jī)(native) | 本機(jī)(native),湊夠4個(gè)字節(jié) | 
| = | 本機(jī)(native) | 標(biāo)準(zhǔn)(standard) | None,按原字節(jié)數(shù) | 
| < | 小端(little-endian) | 標(biāo)準(zhǔn)(standard) | None,按原字節(jié)數(shù) | 
| > | 大端(big-endian) | 標(biāo)準(zhǔn)(standard) | None,按原字節(jié)數(shù) | 
| ! | network(= big-endian大端) | 標(biāo)準(zhǔn)(standard) | None,按原字節(jié)數(shù) | 
2.2.2、格式符
| Format格式符 | C Type(C語言類型) | Python type(Python語言類型) | Standard size | 
| x | pad byte(填充字節(jié)) | no value | |
| c | Char | bytes of length 1 | 1 | 
| b | signed char | integer | 1 | 
| B | unsigned char | integer | 1 | 
| ? | _Bool | bool | 1 | 
| h | Short | integer | 2 | 
| H | unsigned short | integer | 2 | 
| i | int | integer | 4 | 
| I(大寫的i) | unsigned int | integer | 4 | 
| l(小寫的L) | long | integer | 4 | 
| L | unsigned long | integer | 4 | 
| q | long long | integer | 8 | 
| Q | unsigned long long | integer | 8 | 
| n | ssize_t | integer | |
| N | size_t | integer | |
| e | (6) | float | 2 | 
| f | float | float | 4 | 
| d | double | float | 8 | 
| s | char[] | bytes | |
| p | char[] | bytes | |
| P | void* | integer | 
2.3、例子
# 將浮點(diǎn)數(shù)變?yōu)樽址甪_data1 = 123.4567f_data1 = struct.pack('<f', f_data1)u_data1 = struct.unpack('<I', f_data1)f_data2 = -123.4567f_data2 = struct.pack('<f', f_data2)u_data2 = struct.unpack('<I', f_data1)?3、二進(jìn)制文件讀寫
?3.1、二進(jìn)制文件寫
?????????好了,這下我們學(xué)會(huì)了如何將浮點(diǎn)數(shù)或者整形數(shù)據(jù)轉(zhuǎn)換為bytes了,我們現(xiàn)在就看如何將浮點(diǎn)數(shù)或者整型數(shù)據(jù)存到二進(jìn)制文本中。廢話不多說,上代碼:
"""二進(jìn)制文件中的浮點(diǎn)數(shù)存儲(chǔ) """FileName = 'w2.txt'# 以二進(jìn)制的形式打開一個(gè)指定文件夾,如果沒有就創(chuàng)建,如果有就將原來的內(nèi)容覆蓋fid = open(Folder + '/' + FileName, 'wb')s2 = 123.4567s3 = -123.4567# 使用pack函數(shù),將f數(shù)據(jù) 以小子端的方式轉(zhuǎn)換為bytesDataBytes = struct.pack('<f', s2)for i in range(4):fid.write(c_uint8(DataBytes[i])) # 在write的時(shí)候還是轉(zhuǎn)換和成c_uint8,不然會(huì)報(bào)錯(cuò)DataBytes = struct.pack('<f', s3)for i in range(4):fid.write(c_uint8(DataBytes[i]))fid.close()????????最后生成了txt文件,如下所示,將顯示改成hex的方式。
3.2、二進(jìn)制文件讀取? ? ? ??
????????這個(gè)時(shí)候我們并不能認(rèn)為結(jié)果是對的,我們可以用matlab讀取驗(yàn)證或者用Python自己讀取再將bytes數(shù)據(jù)轉(zhuǎn)換為float。
?3.2.1、Matlab讀取二進(jìn)制文件
????????Matlab的代碼如下所示:
close all clear clcfid = fopen('w2.txt','r'); data1 = fread(fid,1,'float'); data2 = fread(fid,1,'float');????????我們以float的方式讀取,發(fā)現(xiàn)讀取的結(jié)果為123.4567和-123.4567,和我們一開始的賦值一致,證明那個(gè)我們這么寫是成功了的。
3.2.2、Python讀取二進(jìn)制文件? ? ?
FileName = 'w2.txt'# 以二進(jìn)制的形式打開一個(gè)指定文件夾,如果沒有就創(chuàng)建,如果有就將原來的內(nèi)容覆蓋fid = open(Folder + '/' + FileName, 'rb')DataBytes1 = fid.read(4) # 這邊讀出來是 bytes# 將bytes解包為指定的數(shù)據(jù)類型S4 = struct.unpack('<f', DataBytes1)DataBytes1 = fid.read(4) # 這邊讀出來是 bytes# 將bytes解包為指定的數(shù)據(jù)類型S5 = struct.unpack('<f', DataBytes1)fid.close()? ??
4、寫在最后
????????好了,關(guān)于Python如何讀寫 文本文件、二進(jìn)制文件、將字符串寫到txt文件中與將float或者int數(shù)據(jù)寫到txt文件的方法大概就寫到這,后面如果還遇到啥就繼續(xù)補(bǔ)充吧。
文中對應(yīng)的代碼鏈接:
Project_File.rar-嵌入式文檔類資源-CSDN文庫https://download.csdn.net/download/yanchuan23/36135222
總結(jié)
以上是生活随笔為你收集整理的Python 学习笔记(3)对txt文件的读与写操作(下)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Python 学习笔记(3)对txt文件
- 下一篇: 合成孔径雷达技术——概述
