누구든지 내가 어떻게 할 수 있는지 말해 줄 수 있습니까?
답변:
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
는 적절한 특수 문자에 맞으면 여러 바이트를 읽을 수 있습니다.
나는 받아 들여진 대답을 좋아한다 : 그것은 간단하고 일을 끝낼 것이다. 또한 대체 구현을 제공하고 싶습니다.
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, 페이지 크기의 배수를 시도 할 수 있음) 해당 청크에있는 문자를 산출한다는 것입니다. 하나씩.
내가 제시하는 코드는 더 큰 파일의 경우 더 빠를 수 있습니다. 예를 들어, 톨스토이가 쓴 전쟁과 평화의 전체 텍스트를 보자 . 다음은 내 타이밍 결과입니다 (OS X 10.7.4를 사용하는 Mac Book Pro; 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.
Raymond Hettinger의 Transforming Code into Beautiful, Idiomatic Python 을 보면서 오늘 새로운 관용구를 배웠습니다 .
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 = 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"
보충을 위해 vvv 매우 큰 줄이 포함 된 파일을 읽고 메모리를 손상시킬 수있는 경우 버퍼로 읽은 다음 각 문자를 산출하는 것을 고려할 수 있습니다.
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)