Como escrever para arquivo em Ruby?

572

Preciso ler os dados do banco de dados e salvá-los em um arquivo de texto.

Como posso fazer isso em Ruby? Existe algum sistema de gerenciamento de arquivos no Ruby?

ohana
fonte

Respostas:

179

The Ruby classe File irá dar-lhe os prós e contras de ::newe ::open, mas o seu pai, a classe IO , entra na profundidade de #reade #write.

jdl
fonte
6
Obrigado @Geoff. É bom ver novos usuários limpando perguntas e respostas desatualizadas. Cria um site melhor em geral.
JDL
7
Eu acho isso irônico. A resposta está muito bem documentada ... mas agora um ano depois, essa pergunta é o primeiro hit do Google. Quando a pergunta foi feita, pode parecer que o OP estava dedicando pouco esforço, mas agora, no que diz respeito ao Google, esta é a melhor fonte.
Jeff
7
Provavelmente porque tudo o que você realmente precisa saber está aqui. A minha é a resposta "ensine um homem a pescar" para quem quer ler os detalhes, e há muitas respostas "dê um peixe a um homem" aqui, bem como para pessoas que querem apenas recortar e colar. Não é de surpreender que essa combinação termine bem no Google.
JDL
1
Portanto, para ser sincero, trabalho em vários idiomas diferentes, o que significa que raramente consigo lembrar a sintaxe de qualquer idioma específico. Pesquisei isso algumas vezes no Google e sempre deslizo além dessa resposta, até a resposta abaixo, porque quando pesquiso no Google StackOverflow geralmente procuro apenas um peixe dang. : p Honestamente, é bom ter os dois. Talvez um dia eu esteja fazendo Ruby o suficiente de uma só vez para me importar com os detalhes.
user435779
2
Isso não responde à pergunta. Apenas aponta para as duas classes que contêm a maioria dos métodos de execução de E / S e não faz menção à conexão com o banco de dados. Isso seria bom como um comentário, mas dificilmente se qualifica como resposta. Percebo que o OP e os muitos leitores que aprovaram esta resposta discordam, e sinceramente não entendo o que eles estavam pensando.
Cary Swoveland
929

Você está procurando o seguinte?

File.open(yourfile, 'w') { |file| file.write("your text") }
Todd R
fonte
8
yourfileé uma variável que contém o nome do arquivo a ser gravado.
B Seven
17
Alternativamente: f = File.open ('name', 'w'); f.write ('texto'); f.close
vish
5
@ish: Eu não recomendaria esta solução, pois o descritor de arquivo ficaria aberto se f.writesurgir uma exceção.
nbarraille
289
Curto e doce:File.write('filename', 'content')
Benjamin Oakes
14
Ainda mais curto e documentado:IO.write('filename', 'content')
Thai
636

Você pode usar a versão curta:

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

Retorna o comprimento escrito; veja :: write para mais detalhes e opções.

Para anexar ao arquivo, se ele já existir, use:

File.write('/path/to/file', 'Some glorious content', mode: 'a')
Sébastien Le Callonnec
fonte
14
Para sua informação, este método abreviado só funciona a partir do Ruby 1.9.3. Não existe esse método nas versões anteriores do 1.9 ou 1.8. Nesse caso, você deve usar o método bloco já postado por @mvndaai
Andrew Burns,
13
Para sua informação, feche corretamente o arquivo quando terminar.
21414 Freedom_Ben
2
IO docs classe dizem que não fechar o arquivo
nruth
7
Isso será anexado a um arquivo ou apenas o substituirá?
21415 Joshua Pinter
8
@ JosPinter: substitui.
mklement0
248

Essa é a abordagem preferida na maioria dos casos:

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

Quando um bloco é passado para File.open , o objeto File será automaticamente fechado quando o bloco terminar.

Se você não passar um bloco para File.open, deve certificar-se de que o arquivo esteja corretamente fechado e que o conteúdo foi gravado no arquivo.

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

Você pode encontrá-lo na documentação :

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;
}
Tombart
fonte
Sim, usando a sintaxe do bloco com {| file | ....} fechará o arquivo quando o bloco fechar.
Wesgarrison #
Legal, obrigado. Eu não tinha certeza disso. Aqui estão mais algumas informações sobre blocos e File.open blog.rubybestpractices.com/posts/rklemme/… também são mencionadas na documentação oficial
Tombart
1
Apenas algo rubi caminho-ish: nil é um objeto, de modo a verificar se um arquivo é nulo, você pergunta o objeto em si em vez de comparar (file.nil em vez de arquivo == nil?)
JCabello
@JCabello claro, essa é definitivamente uma abordagem mais parecida com Ruby, obrigado!
Tombart 26/05
finalmente, uma resposta que mostra que é preciso também verificar o status do arquivo e como lidar com isso, e não apenas um liner que apenas mostra a chamada em aberto.
Nasser
115

A resposta de Zambri encontrada aqui é a melhor.

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

onde suas opções <OPTION>são:

r- Somente leitura. O arquivo deve existir.

w - Crie um arquivo vazio para escrever.

a - Anexar a um arquivo. O arquivo é criado se ele não existir.

r+- Abra um arquivo para atualizar a leitura e a gravação. O arquivo deve existir.

w+ - Crie um arquivo vazio para leitura e gravação.

a+- Abra um arquivo para ler e anexar. O arquivo é criado se não existir.

No seu caso, wé preferível.

mvndaai
fonte
Estou surpreso que uma resposta que copie outra resposta possa receber mais de 100 votos positivos. Posso ver a postagem da primeira frase como um comentário sobre a pergunta, mas é isso.
Cary Swoveland
@CarySwoveland Na verdade, eu concordo com você. O verdadeiro problema é que uma das duas perguntas deveria ter sido marcada como duplicada há muito tempo. Copiei a resposta porque, uma vez que encontrei a pergunta que zanbri havia respondido, e nas próximas vezes em que precisava das mesmas informações, me deparei com essa pergunta primeiro e tive que descobrir como chegar à outra pergunta. Eventualmente, pensei que seria mais fácil ter a resposta dele aqui também. Eu vinculei a sua resposta tão esperançosamente, as pessoas clicaram e deram a ele um voto positivo também.
mvndaai
31

Para aqueles de nós que aprendem pelo exemplo ...

Escreva texto em um arquivo como este:

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

INFORMAÇÕES BÔNUS ...

Leia de volta assim

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

Freqüentemente, quero ler um arquivo na minha área de transferência ***

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

E outras vezes, quero gravar o que está na minha área de transferência em um arquivo ***

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

*** Supõe que você tenha a jóia da área de transferência instalada

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

l3x
fonte
1
Cuidado com a IO.writeopção substituir o conteúdo do arquivo em vez de acrescentar. Anexar com IO.write é um pouco entediante.
fguillen
Não sabe ao certo o que está falando? O comando IO.write não precisa dessa opção para gravar em um arquivo. Eu teria o cuidado de salvar o arquivo no diretório / tmp ou no diretório atual; Caso contrário, você poderá ver uma Errno::ENOENT: No such file or directory @ rb_sysopenmensagem e o arquivo criado com um tamanho de 0 bytes.
L3x
25

Para destruir o conteúdo anterior do arquivo, escreva uma nova string no arquivo:

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

Para acrescentar a um arquivo sem substituir o conteúdo antigo:

open('myfile.txt', "a") { |f| f << 'I am appended string' } 
Marko Tunjic
fonte