35

Python を 1 週間前に始めましたが、同じファイルの読み取りと書き込みについていくつか質問があります。オンラインでいくつかのチュートリアルを実行しましたが、まだ混乱しています。簡単な読み書きファイルを理解できます。

openFile = open("filepath", "r")
readFile = openFile.read()
print readFile 

openFile = open("filepath", "a")
appendFile = openFile.write("\nTest 123")

openFile.close()

しかし、次のことを試してみると、書き込み先のテキスト ファイルに不明なテキストが大量に表示されます。このようなエラーが発生する理由と、以下に示す方法で同じ openFile オブジェクトを使用できない理由を誰でも説明できますか?

# I get an error when I use the codes below:       
openFile = open("filepath", "r+")
writeFile = openFile.write("Test abc")

readFile = openFile.read()
print readFile

openFile.close()

私は自分の問題を明確にしようとします。上記の例では、openFileはファイルを開くために使用されるオブジェクトです。初めて書きたい場合は問題ありません。同じopenFileを使用してファイルを読み取ったり、何かを追加したりしたい場合。発生しないか、エラーが発生します。同じファイルに対して別の読み取り/書き込みアクションを実行する前に、同じ/異なるオープン ファイル オブジェクトを宣言する必要があります。

#I have no problems if I do this:    
openFile = open("filepath", "r+")
writeFile = openFile.write("Test abc")

openFile2 = open("filepath", "r+")
readFile = openFile2.read()
print readFile

openFile.close()

ここで何が間違っていたのか、それとも単に Python の問題なのか誰か教えていただければ幸いです。Python 2.7 を使用しています。ありがとう!

4

4 に答える 4

28

更新された応答:

これは Windows 固有のバグのようです - http://bugs.python.org/issue1521491

http://mail.python.org/pipermail/python-bugs-list/2005-August/029886.htmlで説明されている回避策からの引用

更新のために開いているファイルで読み取りと書き込みを混在させた場合の影響は、それらの間でファイルの位置付け操作 (たとえば、seek()) が発生しない限り、まったく定義されていません。あなたが何を期待しているのかはわかりませんが、挿入することで意図したものが確実に得られる可能性が最も高いようです

fp.seek(fp.tell())

read() と write() の間。

私の最初の応答は、追加のために開かれた同じファイルの読み取り/書き込みがどのように機能するかを示しています。Windows を使用している場合は、明らかに正しくありません。

元の応答:

「r+」モードでは、write メソッドを使用すると、ポインターの場所に基づいて文字列オブジェクトがファイルに書き込まれます。あなたの場合、ファイルの先頭に文字列「Test abc」が追加されます。以下の例を参照してください。

>>> f=open("a","r+")
>>> f.read()
'Test abc\nfasdfafasdfa\nsdfgsd\n'
>>> f.write("foooooooooooooo")
>>> f.close()
>>> f=open("a","r+")
>>> f.read()
'Test abc\nfasdfafasdfa\nsdfgsd\nfoooooooooooooo'

ポインタがすでにファイルの末尾にあったため、文字列「foooooooooooooo」がファイルの末尾に追加されました。

バイナリ ファイルとテキスト ファイルを区別するシステムを使用していますか? その場合、モードとして 'rb+' を使用することをお勧めします。

バイナリ ファイルとテキスト ファイルを区別するシステムでファイルをバイナリ モードで開くには、モードに「b」を追加します。この区別がないシステムでは、「b」を追加しても効果はありません。 http://docs.python.org/2/library/functions.html#open

于 2013-01-11T03:49:10.100 に答える
11

開いているすべてのファイルには、データの読み取りと書き込みの場所を示す暗黙のポインターがあります。a通常、これはデフォルトでファイルの先頭になりますが、 (追加)モードを使用すると、デフォルトでファイルの末尾になります。wまた、モードに追加した場合でも、モードによってファイルが切り捨てられる(つまり、すべてのコンテンツが削除される)ことにも注意して+ください。

N文字を読み書きするときはいつでも、読み取り/書き込みポインタはファイル内でその量だけ前方に移動します。それらを覚えていれば、これを古いカセットテープのように考えると役立つと思います。したがって、次のコードを実行した場合:

fd = open("testfile.txt", "w+")
fd.write("This is a test file.\n")
fd.close()

fd = open("testfile.txt", "r+")
print fd.read(4)
fd.write(" IS")
fd.close()

...最終的には印刷されThis、ファイルの内容は。のままになりますThis IS a test file.。これはread(4)、ポインタがファイルの先頭にあるため、イニシャルがファイルの最初の4文字を返すためです。ポインタをの直後のスペース文字に残すThisため、write(" IS")次の3文字は、スペース(すでに存在するものと同じ)に続いてIS、既存のを置き換えて上書きしますis

ファイルのメソッドを使用しseek()て、特定のポイントにジャンプできます。上記の例の後、以下を実行した場合:

fd = open("testfile.txt", "r+")
fd.seek(10)
fd.write("TEST")
fd.close()

...次に、ファイルにが含まれていることがわかりますThis IS a TEST file.

これはすべてUnixシステムに当てはまり、これらの例をテストして確認できます。ただし、 Windowsシステムでのミキシングread()と問題が発生しました。write()たとえば、Windowsマシンで最初の例を実行すると、正しく印刷されThisますが、後でファイルを確認すると、write()は完全に無視されます。ただし、2番目の例(を使用seek())はWindowsでは正常に機能するようです。

要約すると、Windowsでファイルの途中から読み取り/書き込みを行う場合seek()は、読み取り/書き込みポインターの位置に依存するのではなく、常に明示的に使用することをお勧めします。読み取りのみまたは書き込みのみを実行している場合は、かなり安全です。

最後のポイント-Windowsでパスをリテラル文字列として指定している場合は、バックスラッシュをエスケープすることを忘れないでください。

fd = open("C:\\Users\\johndoe\\Desktop\\testfile.txt", "r+")

rまたは、先頭にを置くことで生の文字列を使用できます。

fd = open(r"C:\Users\johndoe\Desktop\testfile.txt", "r+")

または、最も移植性の高いオプションは、以下を使用することos.path.join()です。

fd = open(os.path.join("C:\\", "Users", "johndoe", "Desktop", "testfile.txt"), "r+")

ファイルIOの詳細については、公式のPythonドキュメントをご覧ください。

于 2013-01-11T10:25:04.760 に答える
3

読み取りと書き込みは、現在のファイル ポインターがある場所で行われ、読み取り/書き込みごとに進みます。あなたの特定のケースでは、に書き込むとopenFile、ファイルポインタがファイルの終わりを指すようになります。最後から読み取ろうとすると、EOF が発生します。seek(0)ファイルポインタをリセットして、ファイルから読み取る前にファイルの先頭を指すようにする必要があります

于 2013-01-11T03:35:27.943 に答える