2009-11-13 4 views

답변

75

이러한 3 가지 선택 사항 사이에 중요한 차이가 있습니다.

  • File.open

    File.open("file").each_line { |line| puts line }

    는 로컬 파일을 열고
  • 당신이 그것에 IO#close를 호출 할 때까지 파일이 열려

open("file").each_line { |line| puts line }

Kernel.open 문자열에 보이는 파일 객체를 반환 그것으로 무엇을 할 것인지 결정할 수 있습니다. 두 번째 경우

open(".irbrc").class # => File 
open("http://google.com/").class # => StringIO 
File.open("http://google.com/") # => Errno::ENOENT: No such file or directory - http://google.com/ 

Kernel#open 의해 리턴 된 객체가 실제로 StringIOhttp://google.com/의 콘텐츠를 보유하고있다. Kernel#openFile 개체를 반환하면 IO#close을 호출 할 때까지 열린 상태로 유지됩니다.

IO.foreach("file") { |line| puts line }

  • IO.foreach

    는 파일을 열고 그것을 읽고 각 라인에 주어진 블록을 호출하고 나중에 파일을 닫습니다.
  • 파일을 닫을 염려가 없습니다.

File.read("file").each { |line| puts line }

당신이 선택을 언급하지 않았다, 그러나 이것은 내가 대부분의 경우에 사용하는 것입니다.

  • File.read은 파일을 완전히 읽고 문자열로 반환합니다.
  • 파일을 닫을 염려가 없습니다.
  • IO.foreach과 비교하면 파일을 다루고 있음을 분명히 알 수 있습니다.
  • 이 메모리 복잡성은 O (n)입니다. 작은 파일을 다루고 있다는 것을 알고 있다면, 이것은 단점이 아닙니다. 그러나 큰 파일 일 수 있고 메모리 복잡성이 O (n)보다 작을 수 있다는 것을 알고 있다면이 선택 사항을 사용하지 마십시오.

그것은이 상황에서 실패

s= File.read("/dev/zero") # => never terminates 
s.each … 

리는 당신에게 루비 문서를 표시하는 도구입니다. 쉘에서 이렇게 사용합니다.

ri File.open 
ri open 
ri IO.foreach 
ri File#each_line 

여기를 사용하면 내가 작성한 거의 모든 것을 찾을 수 있습니다.

+24

정중 한 '리'알림 - 신사의 RTFM에 대한 명성. –

+0

ri에 대한 포인터 주셔서 감사합니다. 그것은 더 친근 할 수 있습니다. "ri File.open"은 나를 찾을 수 없습니다. "open"을 찾으려고 나는 결국 Kernel # orig_open을 찾은 다음 "Kernel # open"을 찾는다. Kernel #을 열지 않고 여러 개의 일치 항목이 있다는 것을 알려 주기만하면된다. #열다*. – Wodin

+0

내 시스템에서'ri File.open'이 작동합니다. – johannes

관련 문제