rails 文件操作的好文章 hastings

轉載自http://hi.baidu.com/rubyonrailsjie/blog/item/28f683f319484314b17ec57c.html

1 打開和關閉一個文件

類方法File.new 打開一個文件,並將它實例化爲一個File對象,他的第一個參數是文件名.
可選的第二個參數叫做 mode string(這個也是從c得來的).他的意思是怎樣打開一個文件(讀,寫或者其他的).默認是'r'(也就是讀).
Ruby代碼
  1. file1 = File.new("one")       # Open for reading  
  2.   
  3. file2 = File.new("two", "w")  # Open for writing  
另外一種new的形式是三個參數的,其中第二個參數是指定了這個文件的原始的權限(經常表示爲一個八進制的數).第三個參數是一系列Ored標誌 的組合.標誌是個常量比如File:CREAT(如果文件不存在則創建它)和File:RDONLY(以只讀方式打開文件)。不過這種形式很少使用:

Ruby代碼
  1. file = File.new("three", 0755, File::CREAT|File::WRONLY)  


出於對操作系統和運行環境的考慮,如果你打開了一個文件的話,你就必須關閉它。當你打開一個文件用於寫時,你更應該這樣做,從而才能免於丟失數據.close方法就是關閉一個文件:

Ruby代碼
  1. out = File.new("captains.log", "w")  
  2. # Process as needed...  
  3. out.close  

這裏還有一個open方法,它的最簡單的形式是和new同義的:
Ruby代碼
  1. trans = File.open("transactions","w")  


但是open方法還能夠帶一個block作爲參數,當存在block時,打開的文件將會做爲一個參數傳遞給block.這時這個文件將會在這個block的作用域裏,保持打開,直到block結束時,自動關閉:

Ruby代碼
  1. File.open("somefile","w") do |file|  
  2.    file.puts "Line 1"  
  3.    file.puts "Line 2"  
  4.    file.puts "Third and final line"  
  5. end  


2 更新文件

假設我們想要打開一個文件用於讀和寫,簡單的加一個'+'號到file mode就行了:
Ruby代碼
  1. f1 = File.new("file1", "r+")  
  2. # Read/write, starting at beginning of file.  
  3. f2 = File.new("file2", "w+")  
  4. # Read/write; truncate existing file or create a new one.  
  5. f3 = File.new("file3", "a+")  
  6. # Read/write; start at end of existing file or create a  
  7. # new one.  


3 追加一個文件

假設我們想要追加一段信息到一個存在文件,當我們打開文件時使用'a'作爲file mode就行了:

Ruby代碼
  1. logfile = File.open("captains_log", "a")  
  2. # Add a line at the end, then close.  
  3. logfile.puts "Stardate 47824.1: Our show has been canceled."  
  4. logfile.close  


4隨機存取一個文件

如果你想隨即存取一個文件,你能夠使用seek方法,它是File從Io繼承而來的.它的最簡單的使用就是指定一個字節位置.這個位置是相對於文件開始的位置(開始的位置是0):
Ruby代碼
  1. # myfile contains only: abcdefghi  
  2. file = File.new("myfile")  
  3. file.seek(5)  
  4. str = file.gets                   # "fghi"  


如果你能確定每一行都是固定的長度,你就能seek指定的行:
Ruby代碼
  1. # Assume 20 bytes per line.  
  2. # Line N starts at byte (N-1)*20  
  3. file = File.new("fixedlines")  
  4. file.seek(5*20)                   # Sixth line!  
  5. # Elegance is left as an exercise.  
如果你想做一個相對的搜索,你就要使用第二個參數,常量 IO::SEEK_CUR表示當前的位置,而第一個參數則就是相對於當前位置的偏移量(可能是負數):

Ruby代碼
  1. file = File.new("somefile")  
  2. file.seek(55)                 # Position is 55  
  3. file.seek(-22, IO::SEEK_CUR)  # Position is 33  
  4. file.seek(47, IO::SEEK_CUR)   # Position is 80  


你也能從文件的結束位置開始搜索:

Ruby代碼
  1. file.seek(-20, IO::SEEK_END)  # twenty bytes from eof  
方法tell得到文件的當前位置,pos是它的別名:

Ruby代碼
  1. file.seek(20)  
  2. pos1 = file.tell             # 20  
  3. file.seek(50, IO::SEEK_CUR)  
  4. pos2 = file.pos              # 70  
rewind方法將會將文件指針的位置設回到開始的位置,也就是0.

5 操作二進制文件

在很久以前,c語言通過在file mode後附加一個'b'來表示將文件用二進制模式打開.在今天,二進制文件的處理已經沒有那麼麻煩了。在ruby中,一個字符串很容易保存一個二進制數據,而且也不用通過任何特殊的方式來讀文件.

可是在windows下是例外,在他下面,二進制文件和文本文件的不同是,在二進制mode下,結束行不能被轉義爲一個單獨的換行,而是被保存爲一個回車換行對.
另外的不同是,在文本模式下 control-Z被作爲文件的結束:

Ruby代碼
  1. # Create a file (in binary mode)  
  2. File.open("myfile","wb") {|f| f.syswrite("12345\0326789\r") }  
  3. # Above note the embedded octal 032 (^Z)  
  4. # Read it as binary  
  5. str = nil  
  6.   
  7. File.open("myfile","rb") {|f| str = f.sysread(15) }  
  8. puts str.size           # 11  
  9. # Read it as text  
  10. str = nil  
  11. File.open("myfile","r") {|f| str = f.sysread(15) }  
  12. puts str.size           # 5  
這邊注意,這些代碼都是在windows下才會打印出後面的結果,如果是在linux兩處都會打印出11.
再看下面的代碼:
Ruby代碼
  1. # Input file contains a single line: Line 1.  
  2. file = File.open("data")  
  3. line = file.readline             # "Line 1.\n"  
  4. puts "#{line.size} characters."   # 8 characters  
  5. file.close  
  6. file = File.open("data","rb")  
  7. line = file.readline             # "Line 1.\r\n"  
  8. puts "#{line.size} characters."   # 9 characters 二進制模式的結尾是一個回車換行對.  
  9. file.close  
binmode方法能夠轉換當前的流爲二進制模式,這邊要注意的是,一旦切換過去,就不能切換回來了:
Ruby代碼
  1. file = File.open("data")  
  2. file.binmode  
  3. line = file.readline             # "Line 1.\r\n"  
  4. puts "#{line.size} characters."   # 9 characters  
  5. file.close  
如果你想使用更底層的輸入輸出,那你可以選擇sysread和syswrite方法,他們接受一定數量的字節作爲參數 .
Ruby代碼
  1. input = File.new("myfile",'a+')  
  2. output = File.new("outfile",'a+')  
  3. instr = input.sysread(10);  
  4. puts instr  
  5. bytes = output.syswrite("This is a test.")  
如果文件指針已經到達文件的結尾時,sysread方法將會拋出一個異常.

這邊要注意 Array 的pack和string的unpack方法,對於處理二進制數據非常有用.
發佈了43 篇原創文章 · 獲贊 10 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章