============================== 5.4 读写å—èŠ‚æ•°æ® ============================== ---------- 问题 ---------- ä½ æƒ³è¯»å†™äºŒè¿›åˆ¶æ–‡ä»¶ï¼Œæ¯”å¦‚å›¾ç‰‡ï¼Œå£°éŸ³æ–‡ä»¶ç‰ç‰ã€‚ ---------- 解决方案 ---------- 使用模å¼ä¸º ``rb`` 或 ``wb`` çš„ ``open()`` 函数æ¥è¯»å–或写入二进制数æ®ã€‚比如: .. code-block:: python # Read the entire file as a single byte string with open('somefile.bin', 'rb') as f: data = f.read() # Write binary data to a file with open('somefile.bin', 'wb') as f: f.write(b'Hello World') 在读å–äºŒè¿›åˆ¶æ•°æ®æ—¶ï¼Œéœ€è¦æŒ‡æ˜Žçš„æ˜¯æ‰€æœ‰è¿”回的数æ®éƒ½æ˜¯å—节å—ç¬¦ä¸²æ ¼å¼çš„ï¼Œè€Œä¸æ˜¯æ–‡æœ¬å—符串。 类似的,在写入的时候,必须ä¿è¯å‚数是以å—节形å¼å¯¹å¤–暴露数æ®çš„对象(比如å—节å—符串,å—节数组对象ç‰)。 ---------- 讨论 ---------- 在读å–二进制数æ®çš„æ—¶å€™ï¼Œå—节å—符串和文本å—符串的è¯ä¹‰å·®å¼‚å¯èƒ½ä¼šå¯¼è‡´ä¸€ä¸ªæ½œåœ¨çš„陷阱。 ç‰¹åˆ«éœ€è¦æ³¨æ„的是,索引和è¿ä»£åŠ¨ä½œè¿”å›žçš„æ˜¯å—èŠ‚çš„å€¼è€Œä¸æ˜¯å—节å—符串。比如: .. code-block:: python >>> # Text string >>> t = 'Hello World' >>> t[0] 'H' >>> for c in t: ... print(c) ... H e l l o ... >>> # Byte string >>> b = b'Hello World' >>> b[0] 72 >>> for c in b: ... print(c) ... 72 101 108 108 111 ... >>> å¦‚æžœä½ æƒ³ä»ŽäºŒè¿›åˆ¶æ¨¡å¼çš„æ–‡ä»¶ä¸è¯»å–或写入文本数æ®ï¼Œå¿…须确ä¿è¦è¿›è¡Œè§£ç å’Œç¼–ç æ“作。比如: .. code-block:: python with open('somefile.bin', 'rb') as f: data = f.read(16) text = data.decode('utf-8') with open('somefile.bin', 'wb') as f: text = 'Hello World' f.write(text.encode('utf-8')) 二进制I/O还有一个鲜为人知的特性就是数组和C结构体类型能直接被写入,而ä¸éœ€è¦ä¸é—´è½¬æ¢ä¸ºè‡ªå·±å¯¹è±¡ã€‚比如: .. code-block:: python import array nums = array.array('i', [1, 2, 3, 4]) with open('data.bin','wb') as f: f.write(nums) 这个适用于任何实现了被称之为"缓冲接å£"的对象,这ç§å¯¹è±¡ä¼šç›´æŽ¥æš´éœ²å…¶åº•层的内å˜ç¼“冲区给能处ç†å®ƒçš„æ“ä½œã€‚ 二进制数æ®çš„写入就是这类æ“作之一。 很多对象还å…许通过使用文件对象的 ``readinto()`` 方法直接读å–二进制数æ®åˆ°å…¶åº•层的内å˜ä¸åŽ»ã€‚æ¯”å¦‚ï¼š .. code-block:: python >>> import array >>> a = array.array('i', [0, 0, 0, 0, 0, 0, 0, 0]) >>> with open('data.bin', 'rb') as f: ... f.readinto(a) ... 16 >>> a array('i', [1, 2, 3, 4, 0, 0, 0, 0]) >>> ä½†æ˜¯ä½¿ç”¨è¿™ç§æŠ€æœ¯çš„æ—¶å€™éœ€è¦æ ¼å¤–å°å¿ƒï¼Œå› 为它通常具有平å°ç›¸å…³æ€§ï¼Œå¹¶ä¸”å¯èƒ½ä¼šä¾èµ–å—é•¿å’Œå—节顺åº(高ä½ä¼˜å…ˆå’Œä½Žä½ä¼˜å…ˆ)。 å¯ä»¥æŸ¥çœ‹5.9å°èŠ‚ä¸å¦å¤–一个读å–二进制数æ®åˆ°å¯ä¿®æ”¹ç¼“冲区的例å。