2016-01-07 72 views
1

這個程序只需要一個文件,刪除它,允許用戶輸入兩行放入空白文件,然後打印文件。必須先閱讀文件才能關閉文件? Python

但是爲什麼我必須關閉文件對象並在顯示新添加的行之前重新打開它?

(注意該文件沒有在這個版本的代碼打印,但如果去掉#的就正確執行。)

from sys import argv 

sript, filename = argv 

print "We will be buliding a new file from an %s" % filename 
print "If you don't want to do this, hit CTRL_C" 
print "If you do, hit and other key" 

raw_input(">>>") 

print "Oppening the file..." 
file_ob = open(filename, "r+") 
file_ob.truncate() 

print "Now we will rewrite this file with the following line" 
line1 = raw_input("The fist line will be :") 
line2 = raw_input("The second line will be:") 

print "Now we're put them into the file" 
file_ob.write("\n\t>>>" + line1 + "\n\n\t>>>" + line2) 

print "And now we will see what is in the file we just made" 
print file_ob.read() 

file_ob.close() 

print "And now we will see what is in the file we just made" 


#file_ob = open(filename, "r+") 
#print file_ob.read() 
#file_ob.close() 
+1

該文件被緩衝。關閉它時,它會強制緩衝區被刷新並寫入文件。考慮使用'open(filename,「r +」)作爲file_ob:'以避免需要關閉。 –

+0

您也可以使用'os.SEEK_SET',因此寫入後不需要關閉和重新打開以讀取文件。 –

+0

@ l'L'l:'os.SEEK_SET'只是一個常量(不是必需的;'SEEK_SET'是默認模式)。你的意思是'file_ob.seek(0)'(第二個參數默認爲'SEEK_SET')? – ShadowRanger

回答

5

File對象默認緩衝;除非你編寫足夠的數據來填充緩衝區,否則在文件被刷新或關閉(隱式刷新)之前它不會寫入文件。這樣做是爲了避免大量(昂貴的)系統調用進行小寫操作。您可以通過致電fileobj.flush()直接強制刷新。

其他一些注意事項:如果目標是打開讀取/寫入和截斷文件,只需以模式'w+'打開,而不是'r+'後跟truncate()。其次,使用with語句,所以您不會意外無法關閉文件(通過省略close,或者由於拋出異常而繞過它)。示例:

with open(filename, "w+") as file_ob: 
    # Don't need to truncate thanks to w+ 
    # Do writes/reads, with explicit flushes if needed 
# When block exited by any means, file is flushed and closed automatically 
+0

謝謝。你能解釋一下'昂貴'的系統調用是什麼意思嗎?只是它使用了很多計算能力? – Ogough

+0

由於各種原因,用戶模式代碼和OS內核代碼之間的轉換非常昂貴;出於穩定性和安全性相關的原因,在用戶代碼和內核代碼之間存在障礙;從用戶模式到內核模式的調用涉及很多工作。您可以搜索「系統調用如何工作」以獲取想法的信息;一個完整的解釋是瘋狂的話題在這裏。 – ShadowRanger

+1

@Ogough:我也會注意到,「昂貴」是相對的。如果我們假設系統調用的開銷只有100微妙,那麼一個'flush'仍然是如此之快,沒有人會注意到它。但是,如果你一次編寫一個字符10,000次,並且Python沒有緩衝,那麼在系統調用開銷上花費的時間太短,僅僅只寫出10KB的數據;如果緩衝減少到3個「系統」通過一次緩衝多達4096個字節來寫入,則開銷將下降到300微秒,這對用戶是不可見的。 – ShadowRanger