Quelles sont toutes les façons courantes de lire un fichier dans Ruby?
Par exemple, voici une méthode:
fileObj = File.new($fileName, "r")
while (line = fileObj.gets)
puts(line)
end
fileObj.close
Je sais que Ruby est extrêmement flexible. Quels sont les avantages / inconvénients de chaque approche?
Réponses:
Il est également possible de fermer explicitement le fichier après comme ci-dessus (passez un bloc pour le
open
fermer pour vous):la source
foreach
plutôtopen
leeach_line
bloc et supprimez-le .f.each { |line| ... }
etf.each_line { |line| ... }
semblent avoir le même comportement (au moins dans Ruby 2.0.0).Le moyen le plus simple si le fichier n'est pas trop long est:
En effet,
IO.read
ouFile.read
fermez automatiquement le fichier, il n'est donc pas nécessaire de l'utiliserFile.open
avec un bloc.la source
IO.read
ouFile.read
fermez également automatiquement le fichier, bien que votre libellé donne l'impression que ce n'est pas le cas.Méfiez-vous des fichiers "slurping". C'est alors que vous lisez le fichier entier en mémoire à la fois.
Le problème est qu'il ne se modifie pas bien. Vous pourriez développer du code avec un fichier de taille raisonnable, puis le mettre en production et découvrir soudain que vous essayez de lire des fichiers mesurant en gigaoctets, et votre hôte se bloque alors qu'il essaie de lire et d'allouer de la mémoire.
Les E / S ligne par ligne sont très rapides et presque toujours aussi efficaces que le slurping. C'est étonnamment rapide en fait.
J'aime utiliser:
ou
Le fichier hérite d'IO et se
foreach
trouve dans IO, vous pouvez donc utiliser l'un ou l'autre.J'ai quelques points de repère montrant l'impact d'essayer de lire de gros fichiers via des
read
E / S ligne par ligne sur " Pourquoi" slurping "un fichier n'est-il pas une bonne pratique? ".la source
Vous pouvez lire le fichier en une seule fois:
Lorsque le fichier est volumineux ou peut être volumineux, il est généralement préférable de le traiter ligne par ligne:
Parfois, vous souhaitez accéder au descripteur de fichier ou contrôler vous-même les lectures:
Dans le cas de fichiers binaires, vous pouvez spécifier un séparateur nul et une taille de bloc, comme ceci:
Enfin, vous pouvez le faire sans bloc, par exemple lors du traitement de plusieurs fichiers simultanément. Dans ce cas, le fichier doit être explicitement fermé (amélioré selon le commentaire de @antinome):
Références: File API et IO API .
la source
for_each
en a pas dans File ou IO. Utilisezforeach
plutôt.while
au lieu deloop
et d'utiliserensure
pour garantir la fermeture du fichier même si une exception est levée. Comme cela (remplacer les points-virgules avec des sauts de ligne):begin; f = File.open('testfile'); while line = f.gets; puts line; end; ensure; f.close; end
.Une méthode simple consiste à utiliser
readlines
:Chaque ligne du fichier d'entrée sera une entrée dans le tableau. La méthode gère l'ouverture et la fermeture du fichier pour vous.
la source
read
ou toute variante, cela va tirer tout le fichier en mémoire, ce qui peut provoquer des problèmes majeurs si le fichier est plus grand que la mémoire disponible. De plus, comme il s'agit d'un tableau, Ruby doit créer le tableau, ce qui ralentit également le processus.http://www.ruby-doc.org/core-1.9.3/IO.html#method-c-read
la source
Je fais habituellement ceci:
Cela vous donnera le texte entier sous forme d'objet chaîne. Cela ne fonctionne que sous Ruby 1.9.
la source
retourne les n dernières lignes de your_file.log ou .txt
la source
Une manière encore plus efficace est la diffusion en continu en demandant au noyau du système d'exploitation d'ouvrir un fichier, puis de lire les octets peu à peu. Lors de la lecture d'un fichier par ligne dans Ruby, les données sont extraites du fichier 512 octets à la fois et divisées en «lignes» après cela.
En mettant en mémoire tampon le contenu du fichier, le nombre d'appels d'E / S est réduit tout en divisant le fichier en segments logiques.
Exemple:
Ajoutez cette classe à votre application en tant qu'objet de service:
Appelez-le et passez la
:each
méthode un bloc:Lisez à ce sujet ici dans cet article détaillé:
Ruby Magic Slurping & Streaming Files par AppSignal
la source
Je pense que cette méthode est la plus "rare". C'est peut-être un peu délicat, mais cela fonctionne si
cat
est installé.la source
content = File.read(filename)