Замена readinto()?Python

Программы на Python
Ответить
Anonymous
 Замена readinto()?

Сообщение Anonymous »

Копирование файла с использованием простого подхода в 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 и не выдает число обработанных предметов). Кроме того, это не решение конечной проблемы особого случая.

Есть ли правильный способ сделать то, что я хочу? Возможно, я просто упускаю из виду простой буферный класс или что-то подобное, который делает то, что я хочу.
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»