ruby wayのIOのひとつ


1ファイルを開く/閉じる
クラスメソッドnewはファイルを開き、ファイル名が最初のパラメータであるFileオブジェクトにインスタンス化します.
オプションの2番目のパラメータはmode stringと呼ばれます(これもcから得られます).彼はどのようにファイルを開くか(読む、書く、または他の)を意味します.デフォルトは「r」(つまり読む)です.
file1 = File.new("one")       # Open for reading

file2 = File.new("two", "w")  # Open for writing

もう1つのnewの形式は3つのパラメータであり、2番目のパラメータはこのファイルの元の権限(常に8進数として表す)を指定する.3番目のパラメータは一連のOredフラグの組み合わせである.フラグは、File:CREAT(ファイルが存在しない場合に作成)やFile:RDONLY(読み取り専用でファイルを開く)などの定数です.しかし、この形式はあまり使われていません.
file = File.new("three", 0755, File::CREAT|File::WRONLY)

オペレーティングシステムと実行環境を考慮して、ファイルを開いたら閉じなければなりません.ファイルを開いて書くときは、データの損失を避けるためにもっとそうしなければなりません.closeメソッドは、ファイルを閉じることです.
out = File.new("captains.log", "w")
# Process as needed...
out.close

ここでopenメソッドは、newと同義の最も簡単な形式です.
trans = File.open("transactions","w")

しかしopenメソッドは、ブロックが存在する場合に開くファイルがパラメータとしてブロックに渡されるブロックをパラメータとして持つこともできる.このとき、このファイルはこのblockの役割ドメインで、blockが終了するまで開いたままになり、自動的に閉じます.
File.open("somefile","w") do |file|
  file.puts "Line 1"
  file.puts "Line 2"
  file.puts "Third and final line"
end

2ファイルの更新
読み取りと書き込みのためにファイルを開くには、file modeに'+'番号を簡単に追加すればいいとします.

f1 = File.new("file1", "r+")
# Read/write, starting at beginning of file.
f2 = File.new("file2", "w+")
# Read/write; truncate existing file or create a new one.
f3 = File.new("file3", "a+")
# Read/write; start at end of existing file or create a
# new one.

3ファイルを追加
存在ファイルに情報を追加したい場合は、ファイルを開くときにfile modeとして「a」を使用すればいいです.
logfile = File.open("captains_log", "a")
# Add a line at the end, then close.
logfile.puts "Stardate 47824.1: Our show has been canceled."
logfile.close

4ファイルへのランダムアクセス
すぐにファイルにアクセスしたい場合は、FileがIoから継承したseekメソッドを使用することができます.最も簡単な使用は、バイトの位置を指定することです.この場所は、ファイルの開始位置(開始位置は0):
# myfile contains only: abcdefghi
file = File.new("myfile")
file.seek(5)
str = file.gets                   # "fghi"

各ローが一定の長さであることを確認できれば、seekで指定したローを選択できます.

# Assume 20 bytes per line.
# Line N starts at byte (N-1)*20
file = File.new("fixedlines")
file.seek(5*20)                   # Sixth line!
# Elegance is left as an exercise.

相対的な検索をしたい場合は、2番目のパラメータ、定数IO::SEEK_を使用します.CURは現在の位置を表し、最初のパラメータは現在の位置に対するオフセット量(負数の可能性があります):
file = File.new("somefile")
file.seek(55)                 # Position is 55
file.seek(-22, IO::SEEK_CUR)  # Position is 33
file.seek(47, IO::SEEK_CUR)   # Position is 80

ファイルの終了位置から検索することもできます.
file.seek(-20, IO::SEEK_END)  # twenty bytes from eof

メソッドtellはファイルの現在の場所を取得し、posはその別名です.
file.seek(20)
pos1 = file.tell             # 20
file.seek(50, IO::SEEK_CUR)
pos2 = file.pos              # 70

rewindメソッドは、ファイルポインタの位置を開始位置、すなわち0に戻す.
5操作バイナリファイル
昔、c言語はfile modeの後に「b」を付加することによってファイルをバイナリモードで開くことを表す.今日、バイナリファイルの処理はもうそんなに面倒ではありません.rubyでは、1つの文字列がバイナリデータを容易に保存し、特別な方法でファイルを読む必要もない.
しかしWindowsでは例外で、彼の下では、バイナリファイルとテキストファイルの違いは、バイナリmodeでは、終了行が単独の改行に変換されるのではなく、1つのリターン改行に保存されることである.
また、テキストモードではcontrol-Zがファイルの終了として扱われる.
# Create a file (in binary mode)
File.open("myfile","wb") {|f| f.syswrite("12345\0326789\r") }
# Above note the embedded octal 032 (^Z)
# Read it as binary
str = nil

File.open("myfile","rb") {|f| str = f.sysread(15) }
puts str.size           # 11
# Read it as text
str = nil
File.open("myfile","r") {|f| str = f.sysread(15) }
puts str.size           # 5

ここで注意して、これらのコードはすべてwindowsの下でやっと後の結果を印刷することができて、linuxの2か所ですべて11を印刷します.
次のコードを見てください.
# Input file contains a single line: Line 1.
file = File.open("data")
line = file.readline             # "Line 1.
" puts "#{line.size} characters." # 8 characters file.close file = File.open("data","rb") line = file.readline # "Line 1.\r
" puts "#{line.size} characters." # 9 characters . file.close

binmodeメソッドは、現在のストリームをバイナリモードに変換することができます.ここで注意したいのは、いったん切り替えると、切り替えることができません.
file = File.open("data")
file.binmode
line = file.readline             # "Line 1.\r
" puts "#{line.size} characters." # 9 characters file.close

より下位の入出力を使用したい場合は、sysreadメソッドとsyswriteメソッドを選択して、パラメータとして一定数のバイトを受け入れることができます.
input = File.new("myfile",'a+')
output = File.new("outfile",'a+')
instr = input.sysread(10);
puts instr
bytes = output.syswrite("This is a test.")

ファイルポインタがファイルの最後に到達とsysreadメソッドは異常を放出する.
ここでArrayのpackとstringのunpackの方法に注意することは,バイナリデータの処理に非常に有用である.
6ファイルロック
オペレーティングシステムはファイルロックを提供し、Fileのflockメソッドはファイルをロックまたはロック解除し、そのパラメータは以下の例のいずれかである.File::LOCK_EX, File::LOCK_NB, File::LOCK_SH, File::LOCK_UN、またはこれらのインスタンスを論理オペレータorで組み合わせる.
file = File.new("somefile")
file.flock(File::LOCK_EX)  #    ;               。
file.flock(File::LOCK_UN)  #     。
file.flock(File::LOCK_SH)  #   ,    ,               。
file.flock(File::LOCK_UN)  #   
locked = file.flock(File::LOCK_EX | File::LOCK_NB)
#lock_nb        ,        false 

7簡単なioの実行
kernelモジュールのioメソッドをよく知っています.これらのメソッドには受信者がいません.例えばgets、puts、そしてp.
私たちがすでに言った方法のほかに、いくつかの方法を覚えなければなりません.putcメソッドは、文字列が指定されている場合、文字列の最初の文字を出力します.
putc(?
) # Output a newline putc("X") # Output the letter X

ここに問題があります.これらの方法には受信者がいません.では、彼らの出力はどこに行きましたか.rubyにおいてunixに対応する3つの標準ioストリームにも3つの定数があり,それらはそれぞれ,stdIN,stdOUT,およびstdERRである.彼らはタイプIOのグローバル変数です.
ここでは、kernel内のすべての出力メソッドの宛先である$stdoutというグローバル変数もあります.$stdoutは、いつでも他のioオブジェクトを指すことができます.
diskfile = File.new("foofile","w")
puts "Hello..."      # prints to stdout
$stdout = diskfile
puts "Goodbye!"      # prints to "foofile"
diskfile.close
$stdout = STDOUT     # reassign to default
File.open("foofile","r") do |file|
	p file.gets
end
puts "That's all."   # prints to stdout

getsメソッドに加えてkernelにはreadlineメソッドとreadlinesメソッドが入力.readlineのフォーマットはgetsと似ていますが、ファイルの最後にEOFErrorが返され、getsはnilが返されます.readlineメソッドはIOに相当する.readlines.
入力はどこから来ましたか?ここには標準的な入力ストリーム$stdinがあり、デフォルトはstdINです.同じようにここにエラーフローがあります($stderr defaulting to stdERR).
ここには、一連のコマンドラインのすべてのファイル名を表すグローバル変数ARGFもあります.彼は本当のfileオブジェクトではありません.
# Read all files, then output again
puts ARGF.read  
# Or more memory-efficient:          ,            .
while ! ARGF.eof?
  puts ARGF.readline
end
# Example:  ruby cat.rb file1 file2 file3

標準入力から読み込むとARGFメソッドはバイパスされます.

# Read a line from standard input
str1 =  STDIN.gets
# Read a line from ARGF
str2 = ARGF.gets #        
# Now read again from standard input
str3 =  STDIN.gets

8バッファリングと非バッファリングを実行するIO
rubyは一般的に自分で内蔵したバッファを使用します.
print "Hello... "
sleep 10
print "Goodbye!
"

このプログラムを実行すると、helloとGoodbyeに気づきます!スクリーンに同時に印刷して後ろに改行文字はありません.
この場合flushメソッドを使用してバッファをリフレッシュできます.ここでは$defoutを受信者として使用します.
print "Hello... "
STDOUT.flush
sleep 10
print "Goodbye!

sync=メソッドはバッファを閉じることができ、syncはこのときのバッファがあるかどうかを返すことができます.

buf_flag = $defout.sync    # true
STDOUT.sync = false
buf_flag = STDOUT.sync     # false

ここでは、getcメソッドが文字を返し、ungetcが文字を押し戻します.

ch = mystream.getc    # ?A
mystream.ungetc(?C)
ch = mystream.getc    # ?C

ここで、sync=falseのように、このバッファは上記とは異なり、上のバッファをオフにすることはできません.ungetcは、sysreadがバッファのない読み取り操作であるため、sysreadのような方法では使用できません.
9操作ファイルの権限と所有権
ファイルの権限と所有者を得るには、Fileのuidメソッドとgidメソッドを使用します.
data = File.stat("somefile")
owner_id = data.uid
group_id = data.gid

クラスFile::Statには、ファイルの権限を返す強力なメソッドmodeがあります.
perms = File.stat("somefile").mode

Fileのchownメソッドは、ファイルの所有者とグループidを変更することができます.
uid = 201
gid = 10
File.chown(uid, gid, "alpha", "beta")
f1 = File.new("delta")
f1.chown(uid, gid)
f2 = File.new("gamma")
f2.chown(nil, gid)      # Keep original owner id

chmodメソッドは、ファイルの権限を変更できます.
File.chmod(0644, "epsilon", "theta")
f = File.new("eta")
f.chmod(0444)

ファイルの読み取りまたは書き込み権限があるかどうかを常に知る必要があります.File::Statクラスのいくつかのインスタンスメソッドを使用できます.
info = File.stat("/tmp/secrets")
rflag = info.readable?
wflag = info.writable?
xflag = info.executable?

有効なユーザーidと実際のユーザーidを区別する必要がある場合があります.readable_real?, writable_real?, およびexecutable_real?:
info = File.stat("/tmp/secrets")
rflag2 = info.readable_real?
wflag2 = info.writable_real?
xflag2 = info.executable_real?

ファイルの所有権は、現在のプロセスの有効なユーザーID(およびグループID)を比較することによってテストできます.File::Statクラスには、インスタンスメソッドowned?grpowned?
これらの方法に注意してください.FileTestにもあります.
 
rflag = FileTest::readable?("pentagon_files")
    # Other methods are: writable? executable? readable_real?
writable_real?
    # executable_real? owned? grpowned?
    # Not found here: uid gid mode

プロセスに関連するumaskメソッドは、新しいファイルの初期権限を決定する.(unmaskの具体的な意味はネット上で検索すればあります).
Fileのクラスメソッドunmaskメソッドでumaskを取得できます.パラメータを指定すると、umaskはこれに設定され、元のumaskが返されます.
File.umask(0237)             # Set the umask
current_umask = File.umask   # 0237

10タイムスタンプ情報の取得と設定
rubyが理解できるタイムスタンプは3つに分けられ、修正時間、アクセス時間、変更時間である.
mtime,atime,ctimはそれぞれこの3つの時間を返します.
t1 = File.mtime("somefile")
# Thu Jan 04 09:03:10 GMT-6:00 2001
t2 = File.atime("somefile")
# Tue Jan 09 10:03:34 GMT-6:00 2001
t3 = File.ctime("somefile")
# Sun Nov 26 23:48:32 GMT-6:00 2000

ちょうどfileインスタンスまたはFileを作成した場合:;Statインスタンスの場合、インスタンスメソッドを使用できます.

myfile = File.new("somefile")
t1 = myfile.mtime
t2 = myfile.atime
t3 = myfile.ctime

info = myfile.stat

t1 = info.mtime

t2 = info.atime

t3 = info.ctime

ファイルのアクセスと変更時間はutimeで変更できます.
today = Time.now
yesterday = today - 86400
File.utime(today, today, "alpha")
File.utime(today, yesterday, "beta", "gamma")

彼は同時に2つの時間を変えるので、もしあなたが1つだけ変えたいなら、先に保存しなければなりません.
mtime = File.mtime("delta")

File.utime(Time.now, mtime, "delta")