Ruby에서 파일을 읽는 일반적인 방법은 무엇입니까?
예를 들어, 여기에 한 가지 방법이 있습니다.
fileObj = File.new($fileName, "r")
while (line = fileObj.gets)
puts(line)
end
fileObj.close
Ruby가 매우 유연하다는 것을 알고 있습니다. 각 접근 방식의 장점 / 단점은 무엇입니까?
Ruby에서 파일을 읽는 일반적인 방법은 무엇입니까?
예를 들어, 여기에 한 가지 방법이 있습니다.
fileObj = File.new($fileName, "r")
while (line = fileObj.gets)
puts(line)
end
fileObj.close
Ruby가 매우 유연하다는 것을 알고 있습니다. 각 접근 방식의 장점 / 단점은 무엇입니까?
답변:
File.open("my/file/path", "r") do |f|
f.each_line do |line|
puts line
end
end
# File is closed automatically at end of block
위와 같이 한 후에 파일을 명시 적으로 닫을 수도 있습니다 (블록을 전달하여 open
닫습니다).
f = File.open("my/file/path", "r")
f.each_line do |line|
puts line
end
f.close
foreach
대신 사용하고 사용 하지 open
마십시오 each_line
.
f.each { |line| ... }
및 f.each_line { |line| ... }
(루비 2.0.0 적어도) 같은 동작을 갖고있는 것 같다.
파일이 너무 길지 않은 경우 가장 쉬운 방법은 다음과 같습니다.
puts File.read(file_name)
실제로 IO.read
또는 File.read
자동으로 파일을 닫으므로 File.open
블록과 함께 사용할 필요가 없습니다 .
IO.read
또는 File.read
자동으로 파일을 닫습니다.
"슬러그"파일에주의하십시오. 그때 전체 파일을 한 번에 메모리로 읽습니다.
문제는 확장 성이 좋지 않다는 것입니다. 합리적인 크기의 파일로 코드를 개발 한 다음 프로덕션 환경에 넣고 갑자기 기가 바이트로 측정되는 파일을 읽으려고 시도하고 호스트가 메모리를 읽고 할당하려고 시도함에 따라 호스트가 멈추고있는 것을 발견 할 수 있습니다.
라인 별 I / O는 매우 빠르며 거의 항상 slurping만큼 효과적입니다. 실제로 놀랍도록 빠릅니다.
나는 사용하고 싶다 :
IO.foreach("testfile") {|x| print "GOT ", x }
또는
File.foreach('testfile') {|x| print "GOT", x }
파일은 IO에서 상속되며 IO에 foreach
있으므로 둘 중 하나를 사용할 수 있습니다.
"파일을"끄는 "이 좋은 방법이 아닌 이유"read
에서 줄 단위 I / O를 통해 큰 파일을 읽는 데 따른 영향을 보여주는 벤치 마크 결과가 있습니다.
한 번에 파일을 읽을 수 있습니다.
content = File.readlines 'file.txt'
content.each_with_index{|line, i| puts "#{i+1}: #{line}"}
파일이 크거나 크면 대개 한 줄씩 처리하는 것이 좋습니다.
File.foreach( 'file.txt' ) do |line|
puts line
end
때로는 파일 핸들에 액세스하거나 읽기를 직접 제어하려는 경우가 있습니다.
File.open( 'file.txt' ) do |f|
loop do
break if not line = f.gets
puts "#{f.lineno}: #{line}"
end
end
이진 파일의 경우 다음과 같이 nil-separator와 블록 크기를 지정할 수 있습니다.
File.open('file.bin', 'rb') do |f|
loop do
break if not buf = f.gets(nil, 80)
puts buf.unpack('H*')
end
end
마지막으로 여러 파일을 동시에 처리 할 때와 같이 블록없이 수행 할 수 있습니다. 이 경우 파일을 명시 적으로 닫아야합니다 (@antinome의 설명에 따라 개선).
begin
f = File.open 'file.txt'
while line = f.gets
puts line
end
ensure
f.close
end
while
대신 사용 loop
하고 사용 ensure
하는 것이 좋습니다 . 이와 같이 (세미콜론을 개행 문자로 대체) : begin; f = File.open('testfile'); while line = f.gets; puts line; end; ensure; f.close; end
.
file_content = File.read('filename with extension');
puts file_content;
나는 보통 이것을한다 :
open(path_in_string, &:read)
이것은 전체 텍스트를 문자열 객체로 제공합니다. Ruby 1.9에서만 작동합니다.
보다 효율적인 방법은 운영 체제의 커널에 파일을 열고 비트 단위로 바이트를 읽도록 요청하여 스트리밍하는 것입니다. Ruby에서 라인 당 파일을 읽을 때 한 번에 512 바이트 파일에서 데이터를 가져 와서 그 후 "라인"으로 분할합니다.
파일 내용을 버퍼링하면 파일을 논리적 청크로 나누면서 I / O 호출 수가 줄어 듭니다.
예:
이 클래스를 앱에 서비스 객체로 추가하십시오.
class MyIO
def initialize(filename)
fd = IO.sysopen(filename)
@io = IO.new(fd)
@buffer = ""
end
def each(&block)
@buffer << @io.sysread(512) until @buffer.include?($/)
line, @buffer = @buffer.split($/, 2)
block.call(line)
each(&block)
rescue EOFError
@io.close
end
end
그것을 호출하고 :each
메소드를 블록에 전달하십시오 .
filename = './somewhere/large-file-4gb.txt'
MyIO.new(filename).each{|x| puts x }
이 자세한 게시물에서 여기를 읽으십시오.