File.open, open and IO.foreach in Ruby, what is the difference?

后端 未结 1 1651
太阳男子
太阳男子 2020-12-22 16:43

All of the following API do the same thing: open a file and call a block for each line. Is there any preference we should use one than another?

File.open(\"f         


        
相关标签:
1条回答
  • 2020-12-22 17:29

    There are important differences beetween those 3 choices.

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

    • File.open opens a local file and returns a file object
    • the file stays open until you call IO#close on it

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

    Kernel.open looks at the string to decide what to do with it.

    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/
    

    In the second case the StringIO object returned by Kernel#open actually holds the content of http://google.com/. If Kernel#open returns a File object, it stays open untill you call IO#close on it.

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

    • IO.foreach opens a file, calls the given block for each line it reads, and closes the file afterwards.
    • You don't have to worry about closing the file.

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

    You didn't mention this choice, but this is the one I would use in most cases.

    • File.read reads a file completely and returns it as a string.
    • You don't have to worry about closing the file.
    • In comparison to IO.foreach this makes it clear, that you are dealing with a file.
    • The memory complexity for this is O(n). If you know you are dealing with a small file, this is no drawback. But if it can be a big file and you know your memory complexity can be smaller than O(n), don't use this choice.

    It fails in this situation:

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

    ri

    ri is a tool which shows you the ruby documentation. You use it like this on your shell.

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

    With this you can find almost everything I wrote here and much more.

    0 讨论(0)
提交回复
热议问题