Il existe des différences importantes entre ces trois choix.
File.open("file").each_line { |line| puts line }
-
File.open
ouvre un fichier local et renvoie un objet fichier
- le fichier reste ouvert jusqu'à ce que vous appeliez
IO#close
sur elle
open("file").each_line { |line| puts line }
Kernel.open
regarde la chaîne pour décider ce qu'il faut en faire.
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/
Dans le second cas, le StringIO
retourné par Kernel#open
contient en fait le contenu de http://google.com/ . Si Kernel#open
renvoie un File
il reste ouvert jusqu'à ce que vous appeliez IO#close
sur elle.
IO.foreach("file") { |line| puts line }
-
IO.foreach
ouvre un fichier, appelle le bloc donné pour chaque ligne qu'il lit, et ferme le fichier ensuite.
- Vous n'avez pas à vous soucier de fermer le fichier.
File.read("file").each { |line| puts line }
Vous n'avez pas mentionné ce choix, mais c'est celui que j'utiliserais dans la plupart des cas.
-
File.read
lit complètement un fichier et le renvoie sous forme de chaîne.
- Vous n'avez pas à vous soucier de fermer le fichier.
- En comparaison avec
IO.foreach
cela indique clairement que vous avez affaire à un fichier.
- La complexité de la mémoire pour cela est O(n). Si vous savez que vous avez affaire à un petit fichier, ce n'est pas un inconvénient. Mais s'il peut s'agir d'un gros fichier et que vous savez que votre complexité mémoire peut être inférieure à O(n), n'utilisez pas ce choix.
Il échoue dans cette situation :
s= File.read("/dev/zero") # => never terminates
s.each …
ri
ri est un outil qui vous montre la documentation ruby. Vous l'utilisez comme ceci sur votre shell.
ri File.open
ri open
ri IO.foreach
ri File#each_line
Avec cela, vous pouvez trouver presque tout ce que j'ai écrit ici et bien plus encore.