2013-01-11 4 views
17

일주일 전에 Python을 시작했으며 동일한 파일을 읽고 쓰는 것에 대해 몇 가지 질문을했습니다. 나는 온라인 튜토리얼을 보았지만 아직도 혼란 스럽다. 단순한 읽기 및 쓰기 파일을 이해할 수 있습니다.초급 파이썬 : 동일한 파일 읽기 및 쓰기

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() 

내가 잘못한 것을 누군가 말해 주면 감사하겠습니다. 아니면 그냥 Pythong 것입니다. 파이썬 2.7을 사용하고 있습니다. 감사!

답변

18

업데이트 응답에서 읽기 전에 이전 seek(0)을 통해 파일의 시작 부분을 가리 키도록, 파일 포인터를 재설정해야합니다

이 윈도우에 특정 버그처럼 보인다 - http://bugs.python.org/issue1521491. 해결 방법에서 인용

http://mail.python.org/pipermail/python-bugs-list/2005-August/029886.html 읽기 사이

the effect of mixing reads with writes on a file open for update is entirely undefined unless a file-positioning operation occurs between them (for example, a seek()). I can't guess what you expect to happen, but seems most likely that what you intend could be obtained reliably by inserting

fp.seek(fp.tell())

()와 쓰기에 설명().

내 원래 응답은 추가 작업을 위해 연 파일과 동일한 파일에서 읽고 쓰기하는 방법을 보여줍니다. Windows를 사용하는 경우에는 사실이 아닙니다.

원래 응답 : 'R +'모드에서

, 포인터가 위치에 따라 파일에 문자열 객체를 작성합니다 쓰기 방법을 사용하여. 귀하의 경우에는 "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 +'를 사용하는 것이 좋습니다.

Append 'b' to the mode to open the file in binary mode, on systems that differentiate between binary and text files; on systems that don’t have this distinction, adding the 'b' has no effect. http://docs.python.org/2/library/functions.html#open

+0

그건 이상한 부분입니다. f = open ("C : \ Users \ MooMoo \ Desktop \ clothes.txt", "r +") 인쇄 f.read() f.write ("foooooooooooooo "). 내가받은 오류 메시지 : 가장 최근에 마지막으로 호출 한 전화 번호 : 파일 "C : \ Users \ MooMoo \ Desktop \ Python27 \ PyProject \ src \ test.py"123 호 f.write ("foooooooooooooo") IOError : [Errno 0] Error f.close() – Cryssie

+0

그러면 Windows와 관련된 문제로 보입니다. 내 답변을 업데이트 중입니다.요지 : 쓰기 전에 f.seek (f.tell())를 사용하십시오. – sidi

2

읽기 및 쓰기는 현재 파일 포인터가있는 곳에서 일어나며 각 읽기/쓰기와 함께 진행됩니다. 특정 경우에 openFile에 쓰면 파일 포인터가 파일 끝을 가리 킵니다. 끝에서 읽으려고하면 EOF가 발생합니다. 당신이

5

모든 열린 파일에는 데이터를 읽고 쓰는 위치를 나타내는 암시 적 포인터가 있습니다.보통이 기본값은 파일의 시작이지만, a (append) 모드를 사용하면 기본값은 파일의 끝입니다. w 모드는 +을 모드에 추가하더라도 파일을 자르 (즉, 모든 콘텐츠를 삭제합니다.) 유의해야합니다.

N 문자를 읽거나 쓸 때마다 읽기/쓰기 포인터가 파일 내에서 그 양만큼 앞으로 이동합니다. 나는 이것을 오래된 카세트 테이프처럼 생각하는 것이 도움이된다고 생각합니다. 그것은 This를 인쇄 한 후 This IS a test file.로 파일 내용을 떠나 결국합니다 ...

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() 

: 그래서, 만약 다음과 같은 코드를 실행. 이는 포인터의 시작 부분에 있기 때문에 처음 read(4)이 파일의 처음 4자를 반환하기 때문입니다. 포인터는 This 바로 뒤에 공백 문자로 놓여 있으므로 다음 write(" IS")은 공백 (이미있는 것과 동일 함)을 덮어 쓴 다음 IS 다음에 기존 is을 바꿉니다.

파일의 seek() 메서드를 사용하여 특정 지점으로 이동할 수 있습니다.

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

... 그런 다음 파일이 지금 This IS a TEST file. 포함되어 있음을 확인할 수있는 것들 : 위의 예 후, 만약 다음과 같은 실행.

이 모든 것은 유닉스 시스템에 적용되며 이러한 예제를 테스트하여 확인할 수 있습니다. 그러나, Windows 시스템에서 read()write()을 섞는 데 문제가있었습니다. 예를 들어 Windows 컴퓨터에서 첫 번째 예제를 실행하면 This이 올바르게 인쇄되지만 이후에 파일을 확인하면 write()은 완전히 무시됩니다. 그러나 두 번째 예제 (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에 대한 추가 정보는 official Python docs에서 확인할 수 있습니다.

+0

안녕하세요 Cartroo, 불행히도, 내가 코드를 이해하고있는 것 같지만 컴파일 할 때 어떻게 든 나에게 보여준 것을주지 않습니다. 예를 들어, 첫 번째 예제 세트에서 제공 한 정확한 코드 세트를 따랐습니다. 파일을 검사 할 때 파일의 텍스트에 "This is a test file"이 표시되고 "This is a test file"이 표시되지 않습니다. 쓰기가 나를 위해 작동하지 않는 것 같습니다. 도움이된다면 Python 2.7을 사용하고 있습니다. – Cryssie

+1

Windows를 사용하는 것과 같은 여러분의 의견에서 보았습니다. 답장에서 언급했듯이, Windows에서도 동일한 파일에서'read()'와'write()'를 섞어 쓰는 것이 좋지 않습니다. 바이너리 모드 - 나는 왜 Windows에 대해 익숙하지 않은지 모르겠다. 그러나'seek()'이 작동하는 것처럼 보이므로이 줄'fd.seek (4)'를 fd.write ("IS")'줄 바로 앞에 추가하십시오. 그 명시적인'seek()'은 Windows에서 작동하도록하는 것으로 보인다. Windows에서 원본 버전이 작동하지 않는 이유에 대한 정보를 추적 할 수 있다면 여기에 다른 설명을 게시 할 것입니다. – Cartroo

+1

이 특정 동작에 대해 궁금해서 새 질문을 제출했습니다. http://stackoverflow.com/questions/14279658/mixing-read-and-write-on-python-files-in-windows – Cartroo