============================== 5.9 读å–二进制数æ®åˆ°å¯å˜ç¼“å†²åŒºä¸ ============================== ---------- 问题 ---------- ä½ æƒ³ç›´æŽ¥è¯»å–二进制数æ®åˆ°ä¸€ä¸ªå¯å˜ç¼“冲区ä¸ï¼Œè€Œä¸éœ€è¦åšä»»ä½•çš„ä¸é—´å¤åˆ¶æ“作。 æˆ–è€…ä½ æƒ³åŽŸåœ°ä¿®æ”¹æ•°æ®å¹¶å°†å®ƒå†™å›žåˆ°ä¸€ä¸ªæ–‡ä»¶ä¸åŽ»ã€‚ ---------- 解决方案 ---------- ä¸ºäº†è¯»å–æ•°æ®åˆ°ä¸€ä¸ªå¯å˜æ•°ç»„ä¸ï¼Œä½¿ç”¨æ–‡ä»¶å¯¹è±¡çš„ ``readinto()`` 方法。比如: .. code-block:: python import os.path def read_into_buffer(filename): buf = bytearray(os.path.getsize(filename)) with open(filename, 'rb') as f: f.readinto(buf) return buf 䏋颿˜¯ä¸€ä¸ªæ¼”示这个函数使用方法的例å: .. code-block:: python >>> # Write a sample file >>> with open('sample.bin', 'wb') as f: ... f.write(b'Hello World') ... >>> buf = read_into_buffer('sample.bin') >>> buf bytearray(b'Hello World') >>> buf[0:5] = b'Hello' >>> buf bytearray(b'Hello World') >>> with open('newsample.bin', 'wb') as f: ... f.write(buf) ... 11 >>> ---------- 讨论 ---------- 文件对象的 ``readinto()`` 方法能被用æ¥ä¸ºé¢„先分é…内å˜çš„æ•°ç»„å¡«å……æ•°æ®ï¼Œç”šè‡³åŒ…括由 ``array`` æ¨¡å—æˆ– ``numpy`` 库创建的数组。 和普通 ``read()`` 方法ä¸åŒçš„æ˜¯ï¼Œ ``readinto()`` å¡«å……å·²å˜åœ¨çš„ç¼“å†²åŒºè€Œä¸æ˜¯ä¸ºæ–°å¯¹è±¡é‡æ–°åˆ†é…内å˜å†è¿”回它们。 å› æ¤ï¼Œä½ å¯ä»¥ä½¿ç”¨å®ƒæ¥é¿å…大é‡çš„内å˜åˆ†é…æ“作。 æ¯”å¦‚ï¼Œå¦‚æžœä½ è¯»å–一个由相åŒå¤§å°çš„记录组æˆçš„äºŒè¿›åˆ¶æ–‡ä»¶æ—¶ï¼Œä½ å¯ä»¥åƒä¸‹é¢è¿™æ ·å†™ï¼š .. code-block:: python record_size = 32 # Size of each record (adjust value) buf = bytearray(record_size) with open('somefile', 'rb') as f: while True: n = f.readinto(buf) if n < record_size: break # Use the contents of buf ... å¦å¤–有一个有趣特性就是 ``memoryview`` , 它å¯ä»¥é€šè¿‡é›¶å¤åˆ¶çš„æ–¹å¼å¯¹å·²å˜åœ¨çš„缓冲区执行切片æ“作,甚至还能修改它的内容。比如: .. code-block:: python >>> buf bytearray(b'Hello World') >>> m1 = memoryview(buf) >>> m2 = m1[-5:] >>> m2 <memory at 0x100681390> >>> m2[:] = b'WORLD' >>> buf bytearray(b'Hello WORLD') >>> 使用 ``f.readinto()`` æ—¶éœ€è¦æ³¨æ„çš„æ˜¯ï¼Œä½ å¿…é¡»æ£€æŸ¥å®ƒçš„è¿”å›žå€¼ï¼Œä¹Ÿå°±æ˜¯å®žé™…è¯»å–çš„å—节数。 如果å—节数å°äºŽç¼“冲区大å°ï¼Œè¡¨æ˜Žæ•°æ®è¢«æˆªæ–æˆ–è€…è¢«ç ´å了(æ¯”å¦‚ä½ æœŸæœ›æ¯æ¬¡è¯»å–指定数é‡çš„å—节)。 最åŽï¼Œç•™å¿ƒè§‚察其他函数库和模å—ä¸å’Œ ``into`` 相关的函数(比如 ``recv_into()`` , ``pack_into()`` ç‰)。 Python的很多其他部分已ç»èƒ½æ”¯æŒç›´æŽ¥çš„I/O或数æ®è®¿é—®æ“作,这些æ“作å¯è¢«ç”¨æ¥å¡«å……或修改数组和缓冲区内容。 关于解æžäºŒè¿›åˆ¶ç»“构和 ``memoryviews`` 使用方法的更高级例å,请å‚考6.12å°èŠ‚ã€‚