我想寫一個實用程序功能,將打開三種不同類型的文件:.bz2,.gz和.txt。我不能僅僅使用File.read
,因爲它給了我壓縮文件的垃圾回收。我試圖用Open3.popen3
,這樣我可以給它一個不同的命令,但我得到一個「沒有這樣的文件或目錄」錯誤與下面的代碼:Open3.popen3函數用'沒有這樣的文件或目錄'或'未打開讀取'來打開bz,gz和txt文件錯誤?
def file_info(file)
cmd = ''
if file.match("bz2") then
cmd = "bzcat #{file}"# | head -20"
elsif file.match("gz") then
cmd = "gunzip -C#{file}"
else
cmd = "cat #{file}"
end
puts "opening file #{file}"
Open3.popen3("#{cmd}", "r+") { |stdin, stdout, stderr|
puts "stdin #{stdin.inspect}"
stdin.read {|line|
puts "line is #{line}"
if line.match('^#') then
else
break
end
}
}
end
> No such file or directory - cat /tmp/test.txt
該文件不存在。我試過使用cmd
而不是#{cmd}
,結果與popen3 cmd
相同。
我決定硬編碼它做的txt文件,如下所示:
def file_info(file)
puts "opening file #{file}"
Open3.popen3("cat", file, "r+") { |stdin, stdout, stderr|
puts "stdin #{stdin.inspect}"
stdin.read {|line|
puts "line is #{line}"
if line.match('^#') then
else
break
end
}
}
end
這讓我回:
stdin #<IO:fd 6>
not opened for reading
我在做什麼錯?
當我這樣做:
Open3.popen3("cat",file) { |stdin, stdout, stderr|
puts "stdout is #{stdout.inspect}"
stdout.read {|line|
puts "line is #{line}"
if line.match('^#') then
puts "found line #{line}"
else
break
end
}
}
我沒有得到任何錯誤和標準輸出線印刷,但也行語句打印出任何東西。
嘗試一些不同的東西后,我想出了一個解決辦法是:
cmd = Array.new
if file.match(/\.bz2\z/) then
cmd = [ 'bzcat', file ]
elsif file.match(/\.gz\z/) then
cmd = [ 'gunzip', '-c', file ]
else
cmd = [ 'cat', file ]
end
Open3.popen3(*cmd) do |stdin, stdout, stderr|
puts "stdout is #{stdout}"
stdout.each do |line|
if line.match('^#') then
puts "line is #{line}"
else
break
end
end
end
什麼`R +`標誌的目的是什麼? – buruzaemon 2011-12-15 01:05:23