Comment écrire dans un fichier en Ruby?


572

J'ai besoin de lire les données de la base de données, puis de les enregistrer dans un fichier texte.

Comment puis-je faire cela en Ruby? Existe-t-il un système de gestion de fichiers dans Ruby?

Réponses:


179

La classe Ruby File vous donnera les tenants et aboutissants de ::newet ::openmais son parent, la classe IO , pénètre dans la profondeur de #readet #write.


6
Merci @Geoff. Il est bon de voir de nouveaux utilisateurs nettoyer les questions et réponses obsolètes. Fait pour un meilleur site dans l'ensemble.
jdl

7
Je trouve cela ironique. La réponse est très bien documentée ... mais maintenant un an plus tard, cette question est le premier hit sur Google. Lorsque la question a été posée, il peut sembler que le PO consacrait peu d'efforts, mais maintenant en ce qui concerne Google, c'est la meilleure source.
Jeff

7
Probablement parce que tout ce que vous devez vraiment savoir est ici. La mienne est la réponse "apprendre à un homme à pêcher" pour ceux qui veulent lire les moindres détails, et il y a beaucoup de réponses "donner à un homme un poisson" ici aussi pour les personnes qui veulent juste couper-coller. Il n'est pas surprenant que cette combinaison finisse bien classée sur Google.
jdl

1
Donc, pour être honnête, je travaille dans de nombreuses langues différentes, ce qui signifie que je me souviens rarement de la syntaxe d'une langue spécifique. J'ai googlé à quelques reprises, et je toujours défiler vers la droite passé cette réponse, à celui ci - dessous, parce que quand je google StackOverflow , je suis généralement à la recherche d'un poisson dang. : p Honnêtement, c'est bien d'avoir les deux. Peut-être qu'un jour je ferai assez de Ruby d'un coup pour que je me soucie des détails.
user435779

2
Cela ne répond pas à la question. Il pointe simplement vers les deux classes qui contiennent la plupart des méthodes d'E / S et ne fait aucune mention de la connexion avec la base de données. Ce serait bien comme un commentaire, mais ne constitue guère une réponse. Je me rends compte que le PO et les nombreux lecteurs qui ont voté en faveur de cette réponse ne sont pas d'accord, et je ne comprends vraiment pas ce qu'ils pensaient.
Cary Swoveland du

929

Recherchez-vous ce qui suit?

File.open(yourfile, 'w') { |file| file.write("your text") }

8
yourfileest une variable qui contient le nom du fichier à écrire.
B Seven

17
Alternativement: f = File.open ('nom', 'w'); f.write ('texte'); f.close
vish

5
@vish: Je ne recommanderais pas cette solution car le descripteur de fichier serait laissé ouvert s'il f.writedéclenche une exception.
nbarraille

289
Court et doux:File.write('filename', 'content')
Benjamin Oakes

14
Encore plus court et documenté:IO.write('filename', 'content')
Thai

636

Vous pouvez utiliser la version courte:

File.write('/path/to/file', 'Some glorious content')

Il renvoie la longueur écrite; voir :: écrire pour plus de détails et d'options.

Pour ajouter au fichier, s'il existe déjà, utilisez:

File.write('/path/to/file', 'Some glorious content', mode: 'a')

14
Pour info, cette méthode raccourcie ne fonctionne qu'à partir de Ruby 1.9.3. Il n'existe aucune méthode de ce type dans les versions antérieures de 1.9 ou 1.8. Dans ce cas, vous devez utiliser la méthode des blocs plus longs publiée par @mvndaai
Andrew Burns

13
Pour info cela ferme correctement le fichier une fois terminé.
Freedom_Ben

2
Les documents de classe IO disent qu'il ferme le fichier
nruth

7
Cela s'ajoutera- t-il à un fichier ou le remplacera-t-il simplement?
Joshua Pinter

8
@JoshPinter: il écrase.
mklement0

248

C'est l'approche préférée dans la plupart des cas:

 File.open(yourfile, 'w') { |file| file.write("your text") }

Lorsqu'un bloc est passé à File.open , l'objet File sera automatiquement fermé à la fin du bloc.

Si vous ne passez pas un bloc à File.open, vous devez vous assurer que le fichier est correctement fermé et que le contenu a été écrit dans le fichier.

begin
  file = File.open("/tmp/some_file", "w")
  file.write("your text") 
rescue IOError => e
  #some error occur, dir not writable etc.
ensure
  file.close unless file.nil?
end

Vous pouvez le trouver dans la documentation :

static VALUE rb_io_s_open(int argc, VALUE *argv, VALUE klass)
{
    VALUE io = rb_class_new_instance(argc, argv, klass);
    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, io, io_close, io);
    }
    return io;
}

Oui, en utilisant la syntaxe de bloc avec {| fichier | ....} fermera le fichier à la fermeture du bloc.
wesgarrison le

Cool merci. Je n'en étais pas sûr. Voici quelques informations supplémentaires sur les blocs et File.open blog.rubybestpractices.com/posts/rklemme/… cela est également mentionné dans la documentation officielle
Tombart

1
Juste quelque chose de rubis: nil est un objet, donc pour vérifier si un fichier est nul, vous demandez l'objet lui-même au lieu de comparer (file.nil? Au lieu de file == nil)
JCabello

@JCabello bien sûr, c'est certainement une approche plus rubis, merci!
Tombart

enfin une réponse qui montre que l'on doit également vérifier l'état du fichier et comment le gérer, et pas seulement un liner qui montre simplement l'appel ouvert.
Nasser

115

La réponse de Zambri trouvée ici est la meilleure.

File.open("out.txt", '<OPTION>') {|f| f.write("write your stuff here") }

où vos options <OPTION>sont:

r- Lecture seulement. Le fichier doit exister.

w - Créez un fichier vide pour l'écriture.

a - Ajouter à un fichier. Le fichier est créé s'il n'existe pas.

r+- Ouvrez un fichier pour mettre à jour la lecture et l'écriture. Le fichier doit exister.

w+ - Créez un fichier vide pour la lecture et l'écriture.

a+- Ouvrez un fichier pour le lire et l'ajouter. Le fichier est créé s'il n'existe pas.

Dans votre cas, wc'est préférable.


Je suis stupéfait qu'une réponse qui copie certes une autre réponse puisse recevoir plus de 100 votes positifs. Je peux voir poster la première phrase comme un commentaire sur la question, mais c'est tout.
Cary Swoveland du

@CarySwoveland Je suis en fait d'accord avec vous. Le vrai problème est que l'une des deux questions aurait dû être marquée en double il y a longtemps. J'ai copié la réponse parce qu'une fois que j'ai trouvé la question à laquelle zanbri avait répondu et les prochaines fois quand j'avais besoin des mêmes informations, je suis tombé sur cette question en premier et j'ai dû trouver comment accéder à l'autre question. Finalement, j'ai pensé qu'il serait plus facile d'avoir sa réponse ici aussi. J'ai lié à sa réponse, alors j'espère que les gens cliqueraient dessus et lui donneraient également une note positive.
mvndaai

31

Pour ceux d'entre nous qui apprennent par l'exemple ...

Écrivez du texte dans un fichier comme celui-ci:

IO.write('/tmp/msg.txt', 'hi')

INFO BONUS ...

Relisez-le comme ceci

IO.read('/tmp/msg.txt')

Souvent, je veux lire un fichier dans mon presse-papiers ***

Clipboard.copy IO.read('/tmp/msg.txt')

Et d'autres fois, je veux écrire ce qui est dans mon presse-papiers dans un fichier ***

IO.write('/tmp/msg.txt', Clipboard.paste)

*** Suppose que le bijou du presse-papiers est installé

Voir: https://rubygems.org/gems/clipboard


1
Attention, l' IO.writeoption écrase le contenu du fichier au lieu de l'ajouter. Ajouter avec IO.write est un peu fastidieux.
fguillen

Vous ne savez pas de quoi vous parlez? La commande IO.write n'a pas besoin de cette option pour écrire dans un fichier. Je ferais bien de sauvegarder le fichier dans le répertoire / tmp ou dans le répertoire courant; Sinon, vous pourriez voir un Errno::ENOENT: No such file or directory @ rb_sysopenmessage et le fichier créé avec une taille de 0 octet.
l3x

25

Pour détruire le contenu précédent du fichier, puis écrivez une nouvelle chaîne dans le fichier:

open('myfile.txt', 'w') { |f| f << "some text or data structures..." } 

Pour ajouter à un fichier sans écraser son ancien contenu:

open('myfile.txt', "a") { |f| f << 'I am appended string' } 
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.