Посмотрите, сколько `file.read` прочитано в Python 3 - PullRequest
0 голосов
/ 05 сентября 2018

Чтение и возврат до размера байтов. Если аргумент опущен, None или отрицательно, данные считываются и возвращаются до достижения EOF. Пустой Объект bytes возвращается, если поток уже находится в EOF.

Если аргумент положительный, а основной исходный поток не интерактивное, несколько необработанных чтений могут быть выполнены для удовлетворения байта рассчитывать (если EOF не достигнут первым). Но для интерактивных потоков, будет выдано не более одного необработанного чтения, , и короткий результат не означает что EOF неизбежен.

BlockingIOError вызывается, если основной исходный поток находится в режим блокировки, и в данный момент нет доступных данных.

io.BufferedIOBase.read

Если результат, возвращаемый операцией чтения, может иметь длину меньше заданной или ожидаемой суммы; и до сих пор не предполагают, что EOF был достигнут, какой надежный способ разделения будет наиболее надежным?

import os
import io

def reliable_read(file_obj, amount=None, chk_size=2):
    file_size = os.fstat(file_obj.file_no()).st_size
    data = b"" if isinstance(file_obj, io.BufferedReader) else ""
    amount_read = 0

    if amount is None:
        amount = file_size
    while amount_read < amount:
       data += file_obj.read(chk_size)
    return data

Первоначально я думал, что по какой-то причине, чем меньше размер фрагмента, тем выше вероятность того, что чтение будет выполнено полностью; однако я точно не знаю, так ли это, поэтому он проверяет надежность вышеуказанной функции. Это также неэффективно, так как chk_size приближается к 1, количество вызовов функций приближается к file_size, что не оптимально для действительно больших файлов.

По сути, без использования CFFI для импорта fopen, fread и fclose - какая встроенная функция или библиотека существует, которая обеспечивает надежное чтение, также в сущности моего названия; функция, которая возвращает точное прочитанное количество, либо помещая буфер чтения в список по ссылке, либо в виде кортежа (data, n_read).

1 Ответ

0 голосов
/ 05 сентября 2018

примечание в цитируемой вами документации:

множественные необработанные чтения могут быть выполнены для удовлетворения количества байтов

Что означает, что этот цикл бесполезен. Необработанное чтение - это чтение, выполняемое ОС с использованием read(), которое может возвращать меньше, чем запрошено в некоторых входных потоках.

while amount_read < amount:
   data += file_obj.read(chk_size)

(плюс цикл не обновляется amount_read, поэтому я подозреваю, что в нем есть ошибка)

Поскольку вы используете файловый интерфейс Python (не os.read), Python собирается сделать это внутренне, с возможными ошибками в процессе, если одно или несколько внутренних необработанных чтений, необходимых для завершения операции, не удаются.

Вы не контролируете внутреннюю часть read, поэтому вам просто нужно сделать:

data = file_obj.read(amount)

Если вы не хотите использовать интерфейс Pyhton, перейдите на os.read с полным контролем и необработанной проверкой ошибок, которыми вам придется управлять.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...