4
是否有從文件描述符(不是IO類對象)直接讀入bytearray的方法?python從fd直接讀入bytearray
現在,我使用臨時FileIO
對象進行調解,是這樣的:
def fd_readinto(fd, ba):
fio = io.FileIO(fd, closefd = False)
return fio.readinto(ba)
是否有從文件描述符(不是IO類對象)直接讀入bytearray的方法?python從fd直接讀入bytearray
現在,我使用臨時FileIO
對象進行調解,是這樣的:
def fd_readinto(fd, ba):
fio = io.FileIO(fd, closefd = False)
return fio.readinto(ba)
沒有的功能,這是否和你的方法是目前爲止最快的方法。
我要建議bytearray(mmap)
的array.fromfile
,並且使用bytearray
和memoryview
甚至一個自制os.read()
,但FileIO.readinto
是尖叫快速。
import os
import mmap, io, array
import timeit
fn = 'path_to_largish_file'
def fd_readinto_mmap(fd, ba):
m = mmap.mmap(fd, 0, access=mmap.ACCESS_READ)
ba.extend(m)
m.close()
def fd_readinto_fio(fd, ba):
with io.FileIO(fd, closefd = False) as fio:
fio.readinto(ba)
def fd_readinto_array(fd, ba):
ar = array.array('c')
sz = os.fstat(fd).st_size
fp = os.fdopen(fd, 'rb')
ar.fromfile(fp, sz)
ba.extend(ar)
def fd_readinto_mv(fd, ba):
stat = os.fstat(fd)
blksize = getattr(stat, 'st_blksize', 4096)
bufsize = stat.st_size
buf = bytearray(bufsize)
m = memoryview(buf)
while True:
b = os.read(fd, blksize)
s = len(b)
if not s: break
m[:s], m = b, m[s:]
writtenbytes = buffer(buf, 0, bufsize-len(m))
ba.extend(writtenbytes)
setup = """
from __main__ import fn, fd_readinto_mmap, fd_readinto_fio, fd_readinto_array, fd_readinto_mv, reset_fd
import os
openfd = lambda : os.open(fn, os.O_RDONLY)
closefd = lambda fd: os.close(fd)
"""
reps = 2
tests = {
'fio' : "fd=openfd(); fd_readinto_fio(fd, bytearray()); closefd(fd)",
'mmap': "fd=openfd(); fd_readinto_mmap(fd, bytearray()); closefd(fd)",
'array': "fd=openfd(); fd_readinto_array(fd, bytearray());",
'mv' : "fd=openfd(); fd_readinto_mv(fd, bytearray()); closefd(fd)",
}
width = max(map(len, tests))
for n,t in tests.iteritems():
time = timeit.timeit(t, setup, number=reps)
print ("{:%s} {}" % width).format(n, time)
在我的系統,FileIO
是快幾個數量級。 FileIO.readinto
對於文件大小似乎也幾乎是恆定的。 (不知道這怎麼可能。)
mmap 4.86922478676
array 4.19783091545
mv 7.75051403046
fio 9.29832458496e-05
我不想說這個 - 但你的分析是有缺陷的。根據這些結果,fio的速度比其他所有東西快100,000倍(這導致我的左眉毛提高到相當高的程度)。我花了一些時間檢查你的代碼,發現了這個缺陷。根據文檔(http://docs.python.org/2.7/library/io.html#io.RawIOBase.readinto),「... readinto(b)最多可讀取len(b)個字節......」在你的例子中,你傳遞一個空的bytearray(),所以它返回零字節。如果您預先將bytearray()擴展爲適當的大小,您將獲得更理想的結果。 –
user590028