Python - Как использовать custom buffer_size в io.BufferedReader? - PullRequest
0 голосов
/ 08 ноября 2018

Насколько я понимаю, аргумент buffer_size для io.BufferedReader должен управлять размером буфера чтения, передаваемого базовому считывателю.

Однако я не вижу такого поведения. Вместо этого, когда я reader.read() весь файл, io.DEFAULT_BUFFER_SIZE используется и buffer_size игнорируется. Когда I reader.read(length), length используется в качестве размера буфера, а аргумент buffer_size снова игнорируется.

Минимальный пример:

import io

class MyReader(io.RawIOBase):

    def __init__(self, length):
        self.length = length
        self.position = 0

    def readinto(self, b):
        print('read buffer length: %d' % len(b))
        length = min(len(b), self.length - self.position)
        self.position += length
        b[:length] = 'a' * length
        return length

    def readable(self):
        return True

    def seekable(self):
        return False


print('# read entire file')
reader = io.BufferedReader(MyReader(20000), buffer_size=100)
print('output length: %d' % len(reader.read()))

print('\n# read part of file file')
reader = io.BufferedReader(MyReader(20000), buffer_size=100)
print('output length: %d' % len(reader.read(10000)))

print('\n# read beyond end of file file')
reader = io.BufferedReader(MyReader(20000), buffer_size=100)
print 'output length: %d' % len(reader.read(30000))

Выходы:

# read entire file
read buffer length: 8192
read buffer length: 8192
read buffer length: 8192
read buffer length: 8192
read buffer length: 8192
output length: 20000

# read part of file file
read buffer length: 10000
output length: 10000

# read beyond end of file file
read buffer length: 30000
read buffer length: 10000
output length: 20000

Я неправильно понимаю, как должен работать BufferedReader?

1 Ответ

0 голосов
/ 08 ноября 2018

Смысл BufferedIOReader состоит в том, чтобы сохранить внутренний буфер, и вы устанавливаете размер этого буфера.Этот буфер используется для удовлетворения меньших операций чтения, чтобы избежать многих вызовов чтения на более медленном устройстве ввода-вывода.

Однако буфер не пытается ограничить размер операций чтения!

Из документации io.BufferedIOReader :

При считывании данных из этого объекта может быть запрошен больший объем данных из базового необработанного потока и сохранен ввнутренний буфер.Буферизованные данные затем могут быть возвращены непосредственно при последующих чтениях.

Объект наследуется от io.BufferedIOBase, что гласит:

Основное различиеRawIOBase означает, что методы read(), readinto() и write() будут пытаться (соответственно) прочитать столько входных данных, сколько требуется, или использовать весь заданный вывод за счет выполнения, возможно, более одного системного вызова.

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

Буфер вступит в игру, если вы будете читать меньшими блоками:

>>> reader = io.BufferedReader(MyReader(2048), buffer_size=512)
>>> __ = reader.read(42)  # initial read, fill buffer
read buffer length: 512
>>> __ = reader.read(123)  # within the buffer, no read to underlying file needed
>>> __ = reader.read(456)  # deplete buffer, another read needed to re-fill
read buffer length: 512
>>> __ = reader.read(123)  # within the buffer, no read to underlying file needed
>>> __ = reader.read()     # read until end, uses larger blocks to read from wrapped file
read buffer length: 8192
read buffer length: 8192
read buffer length: 8192
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...