Код: Выделить всё
def copyfileobj(fsrc, fdst, length=16*1024):
"""copy data from file-like object fsrc to file-like object fdst"""
while 1:
buf = fsrc.read(length)
if not buf:
break
fdst.write(buf)
К сожалению, у этого есть недостатки в моем специальном сценарии использования (включая многопоточность и очень большие буферы) [курсив добавлен позже]. Во-первых, это означает, что при каждом вызове read() выделяется новый фрагмент памяти, и когда buf перезаписывается на следующей итерации, эта память освобождается только для того, чтобы снова выделить новую память для той же цели. Это может замедлить весь процесс и создать ненужную нагрузку на хост.
Чтобы избежать этого, я использую метод file.readinto(), который, к сожалению, задокументирован как устаревший и «не используется»:
Код: Выделить всё
def copyfileobj(fsrc, fdst, length=16*1024):
"""copy data from file-like object fsrc to file-like object fdst"""
buffer = array.array('c')
buffer.fromstring('-' * length)
while True:
count = fsrc.readinto(buffer)
if count == 0:
break
if count != len(buffer):
fdst.write(buffer.toString()[:count])
else:
buf.tofile(fdst)
Я посмотрел на array.array.fromfile(), но его нельзя использовать для чтения «всего, что есть» (читает, затем выдает EOFError и не выдает число обработанных предметов). Кроме того, это не решение конечной проблемы особого случая.
Есть ли правильный способ сделать то, что я хочу? Возможно, я просто упускаю из виду простой буферный класс или что-то подобное, который делает то, что я хочу.
Мобильная версия