Копирование файла с использованием прямого подхода в Python обычно выглядит следующим образом:
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)
(кстати, этот фрагмент кода взят из shutil.py).
К сожалениюэто имеет недостатки в моем особом случае использования (включая многопоточность и очень большие буферы) [Часть, выделенная курсивом, добавленная позже] .Во-первых, это означает, что при каждом вызове 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)
Мое решение работает, но есть и два недостатка: во-первых, readinto () не должен использоваться.Это может уйти (говорит документация).Во-вторых, с readinto () я не могу решить, сколько байтов я хочу прочитать в буфер, а с buffer.tofile () я не могу решить, сколько я хочу записать, следовательно, громоздкий особый случай для последнего блока (что также неоправданнодорогой).
Я посмотрел на array.array.fromfile (), но его нельзя использовать для чтения "все, что есть" (читает, затем выдает EOFError и не передает количество обработанныхПредметы).Кроме того, это не решение конечной особой проблемы.
Есть ли правильный способ сделать то, что я хочу сделать?Может быть, я просто пропускаю простой класс буфера или аналогичный класс, который делает то, что я хочу.