Как работают методы write (), read () и getvalue () Python io.BytesIO? - PullRequest
0 голосов
/ 26 ноября 2018

Я пытаюсь понять write () и read () методы io.BytesIO .Насколько я понимаю, я мог бы использовать io.BytesIO , как если бы я использовал объект File.

import io
in_memory = io.BytesIO(b'hello')
print( in_memory.read() )

Приведенный выше код вернет b'hello ' какожидается, но код ниже вернет пустую строку b '' .

import io
in_memory = io.BytesIO(b'hello')
in_memory.write(b' world')
print( in_memory.read() )

Мои вопросы:

-Что именно io.BytesIO.write(b' world') делает именно?

-В чем разница между io.BytesIO.read () и io.BytesIO.getvalue () ?

Я предполагаю, что ответотносится к io.BytesIO как к объекту потока, но большая картина мне не ясна.

Ответы [ 3 ]

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

Проблема в том, что вы находитесь в конце потока.Думайте о позиции как курсор.После того как вы написали b' world', ваш курсор находится в конце потока.Когда вы пытаетесь .read(), вы читаете все после позиции курсора, что является ничем, поэтому вы получаете пустую строку теста.

Для перемещения по потоку вы можете использовать метод .seek:

>>> import io
>>> in_memory = io.BytesIO(b'hello', )
>>> in_memory.write(b' world')
>>> in_memory.seek(0)  # go to the start of the stream
>>> print(in_memory.read())
b' world'

Обратите внимание, что, как и файловый поток в режиме write ('w'), начальные байты b'hello' были перезаписаны вашей записью b' world'.

.getvalue() просто возвращает все содержимое потока независимо от текущей позиции.

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

BytesIO ведет себя как файл, только тот, который вы можете читать и писать.Может быть, запутанная часть в том, что позиция чтения и письма одинакова.Итак, сначала вы делаете:

in_memory = io.BytesIO(b'hello')

Это дает вам буфер байтов в in_memory с содержимым b'hello' и с позицией чтения / записи в начале (перед первым b'h').Когда вы делаете:

in_memory.write(b' world')

Вы фактически перезаписываете b'hello' с помощью b' world' (и фактически получаете еще один байт), и теперь у вас есть позиция в конце (после последнего b'd'),Поэтому, когда вы делаете:

print( in_memory.read() )

Вы ничего не видите, потому что нечего читать после текущей позиции.Однако вы можете использовать seek для перемещения позиции, поэтому если вы сделаете

import io
in_memory = io.BytesIO(b'hello')
in_memory.write(b' world')
in_memory.seek(0)
print( in_memory.read() )

Вы получите:

b' world'

Обратите внимание, что вы не делаетесм. начальный b'hello', потому что он был перезаписан.Если вы хотите написать после исходного содержимого, вы можете сначала выполнить поиск до конца:

import io
in_memory = io.BytesIO(b'hello')
in_memory.seek(0, 2)
in_memory.write(b' world')
in_memory.seek(0)
print( in_memory.read() )

Вывод:

b'hello world'

РЕДАКТИРОВАТЬ: О getvalue, как указано в других ответах, он дает вам полный внутренний буфер, независимо от текущей позиции.Эта операция явно недоступна для файлов.

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

это поток памяти, но все же поток.Позиция сохраняется, так что, как и любой другой поток, если вы пытаетесь прочитать после записи, вы должны изменить положение:

import io
in_memory = io.BytesIO(b'hello')
in_memory.seek(0,2)   # seek to end, else we overwrite
in_memory.write(b' world')
in_memory.seek(0)    # seek to start
print( in_memory.read() )

печатает:

b'hello world'

, а in_memory.getvalue()не нужно окончательное значение seek(0), поскольку оно возвращает содержимое потока из позиции 0.

...