Хтось може сказати мені, як я можу це зробити?
Відповіді:
with open(filename) as f:
while True:
c = f.read(1)
if not c:
print "End of file"
break
print "Read a character:", c
result = open(filename).read()
а потім читаю result
символ за символом.
with open(filename, encoding='Windows-1250') as f:
open(filename, "r")
vs open(filename, "rb")
може призвести до різної кількості ітерацій (принаймні, говорячи про Python 3). Режим "r" може прочитати кілька байтів, щоб отримати, c
якщо він потрапляє у відповідний спеціальний символ.
спочатку відкрийте файл:
with open("filename") as fileobj:
for line in fileobj:
for ch in line:
print ch
Мені подобається прийнята відповідь: вона прямолінійна і допоможе зробити роботу. Я також хотів би запропонувати альтернативну реалізацію:
def chunks(filename, buffer_size=4096):
"""Reads `filename` in chunks of `buffer_size` bytes and yields each chunk
until no more characters can be read; the last chunk will most likely have
less than `buffer_size` bytes.
:param str filename: Path to the file
:param int buffer_size: Buffer size, in bytes (default is 4096)
:return: Yields chunks of `buffer_size` size until exhausting the file
:rtype: str
"""
with open(filename, "rb") as fp:
chunk = fp.read(buffer_size)
while chunk:
yield chunk
chunk = fp.read(buffer_size)
def chars(filename, buffersize=4096):
"""Yields the contents of file `filename` character-by-character. Warning:
will only work for encodings where one character is encoded as one byte.
:param str filename: Path to the file
:param int buffer_size: Buffer size for the underlying chunks,
in bytes (default is 4096)
:return: Yields the contents of `filename` character-by-character.
:rtype: char
"""
for chunk in chunks(filename, buffersize):
for char in chunk:
yield char
def main(buffersize, filenames):
"""Reads several files character by character and redirects their contents
to `/dev/null`.
"""
for filename in filenames:
with open("/dev/null", "wb") as fp:
for char in chars(filename, buffersize):
fp.write(char)
if __name__ == "__main__":
# Try reading several files varying the buffer size
import sys
buffersize = int(sys.argv[1])
filenames = sys.argv[2:]
sys.exit(main(buffersize, filenames))
Я пропоную код, по суті, такий самий, як і ваша прийнята відповідь: прочитайте із файлу задану кількість байтів. Різниця полягає в тому, що спочатку він читає хороший шматок даних (4006 є гарним за замовчуванням для X86, але ви можете спробувати 1024 або 8192; будь-який кратний розміру вашої сторінки), а потім він дає символи в цьому шматку по одному.
Наведений вами код може бути швидшим для великих файлів. Візьмемо, наприклад, увесь текст "Війни і миру" Толстого . Це мої результати синхронізації (Mac Book Pro з використанням OS X 10.7.4; so.py - це ім’я, яке я дав коду, який я вставив):
$ time python so.py 1 2600.txt.utf-8
python so.py 1 2600.txt.utf-8 3.79s user 0.01s system 99% cpu 3.808 total
$ time python so.py 4096 2600.txt.utf-8
python so.py 4096 2600.txt.utf-8 1.31s user 0.01s system 99% cpu 1.318 total
Тепер: не сприймайте розмір буфера 4096
як загальну істину; подивіться на результати, які я отримую для різних розмірів (розмір буфера (байти) проти часу стінки (сек)):
2 2.726
4 1.948
8 1.693
16 1.534
32 1.525
64 1.398
128 1.432
256 1.377
512 1.347
1024 1.442
2048 1.316
4096 1.318
Як бачите, ви можете почати бачити приріст раніше (і мої терміни, швидше за все, дуже неточні); розмір буфера - це компроміс між продуктивністю та пам'яттю. За замовчуванням 4096 - це лише розумний вибір, але, як завжди, вимірюйте спочатку.
Сам Python може допомогти вам у цьому, в інтерактивному режимі:
>>> help(file.read)
Help on method_descriptor:
read(...)
read([size]) -> read at most size bytes, returned as a string.
If the size argument is negative or omitted, read until EOF is reached.
Notice that when in non-blocking mode, less data than what was requested
may be returned, even if no size parameter was given.
Сьогодні я дізнався нову ідіому для цього, дивлячись « Перетворення коду Реймонда Хеттінгера в красивий ідіоматичний пітон» :
import functools
with open(filename) as f:
f_read_ch = functools.partial(f.read, 1)
for ch in iter(f_read_ch, ''):
print 'Read a character:', repr(ch)
Просто прочитайте одного персонажа
f.read(1)
Спробуйте спробувати f.read(1)
, що, безумовно, правильно і правильно робити.
f = open('hi.txt', 'w')
f.write('0123456789abcdef')
f.close()
f = open('hej.txt', 'r')
f.seek(12)
print f.read(1) # This will read just "c"
Щоб зробити доповнення, якщо ви читаєте файл, який містить рядок, який є vvvvery величезним, що може зіпсувати вашу пам'ять, ви можете розглянути їх читання в буфер, а потім дати кожен символ
def read_char(inputfile, buffersize=10240):
with open(inputfile, 'r') as f:
while True:
buf = f.read(buffersize)
if not buf:
break
for char in buf:
yield char
yield '' #handle the scene that the file is empty
if __name__ == "__main__":
for word in read_char('./very_large_file.txt'):
process(char)
#reading out the file at once in a list and then printing one-by-one
f=open('file.txt')
for i in list(f.read()):
print(i)
os.system("stty -icanon -echo")
while True:
raw_c = sys.stdin.buffer.peek()
c = sys.stdin.read(1)
print(f"Char: {c}")