バッファにすべてのコンテンツをロードせずにファイルを読み書きするにはどうすればよいですか?
4 に答える
ファイルオブジェクトは反復可能です:
with open(filename) as f:
for line in f:
do_something(line)
それらを反復処理すると、一度に 1 行が生成されます (ファイル全体がメモリに保存されるわけではありません)。
ファイルの書き込みも同様に簡単です。
with open(filename,'w') as f:
for x in get_data():
f.write(x)
writelines
または、ジェネレーターを渡すメソッドを使用することもできます。例えばf.writelines(get_data())
ここで、get_data
次のように定義できます。
def get_data():
for i in xrange(200):
yield '%d\n'%i
seek for を使用して、読み取りたいファイルの部分に移動できます。
ドキュメントから:
ファイル オブジェクトの位置を変更するには、f.seek(offset, from_what) を使用します。位置は、基準点にオフセットを追加して計算されます。基準点は from_what 引数によって選択されます。from_what の値が 0 の場合はファイルの先頭から測定され、1 の場合は現在のファイル位置が使用され、2 の場合はファイルの末尾が基準点として使用されます。from_what は省略可能で、デフォルトは 0 で、ファイルの先頭を基準点として使用します。
シーク後は、通常どおり最初にロードされたファイルと同じように、バイトまたは行のいずれかを読み取ることができます。
関数の例を次に示します。
def special_read_file(filename, location, length):
file_handle = open(filename)
file_handle.seek(location, 0)
return file_handle.read(length)
場所と長さはバイト単位です。file_name は、読み取りたいファイルの場所の文字列になります。
シークを使用すると、いくつかの素晴らしく興味深いことができます。これを使用してファイル内をジャンプするため、ファイルの内容をローカルに保存する必要がなく、行を反復処理できます。
with
他のいくつかの回答がすでに述べているように、 を使用してファイル行を反復処理することはfor line in file
、システムのコンテンツを軽く保つ良い方法です。ただし、file_handle を渡す方がはるかに簡単で、その一部を開いたり閉じたり、読み取ったりする必要はありません。ハンドルを開いて、その特定のファイルが必要なときにいつでも必要な場所から読み取ることができます。
ここでは、通常どおりに機能するジェネレーター関数を作成しました。ファイルのどの部分から読み取りを開始するかを指定できるのはユーザーだけです。
def read_handle_from(file_handle, start_point):
file_handle.seek(start_point, 0)
for line in file_handle:
yield line
my_file_handle = open(file_name)
for line in read_handle_from(my_file_handle, 2000):
#do stuff
関数を簡単に変更して、読み取る行数または読み取るバイト数を制限することができます。
自分の好きなように使用するための関数とジェネレーターを作成するのは非常に簡単です。Python で独自の関数を作成することを恐れないでください。すべてを組み込む必要はありません。
ファイルオブジェクトは反復可能であるため、好きなことを行うことができます。
たとえば、入力から出力まで 1 行おきに書き込むには、次のようにします。
from itertools import islice
with open('input') as fin, open('output', 'w') as fout:
every_other = islice(fin, None, None, 2)
fout.writelines(every_other)
はい、できます。たとえば、次の例では、一度に 1 行ずつファイルを調べます。
with open('data.txt') as f:
for line in f:
print line.strip()
これは、ファイル全体をメモリにロードしません。