Quais são as formas mais comuns de ler um arquivo no Ruby?
Por exemplo, aqui está um método:
fileObj = File.new($fileName, "r")
while (line = fileObj.gets)
puts(line)
end
fileObj.close
Eu sei que Ruby é extremamente flexível. Quais são os benefícios / desvantagens de cada abordagem?
Respostas:
Também é possível fechar explicitamente o arquivo depois como acima (passe um bloco para fechá-
open
lo para você):fonte
foreach
vez deopen
e dispense oeach_line
bloco.f.each { |line| ... }
ef.each_line { |line| ... }
parece ter o mesmo comportamento (pelo menos no Ruby 2.0.0).A maneira mais fácil se o arquivo não for muito longo é:
De fato,
IO.read
ouFile.read
feche o arquivo automaticamente, para que não haja necessidade de usarFile.open
com um bloco.fonte
IO.read
ouFile.read
feche o arquivo automaticamente, embora suas palavras pareçam não parecer.Desconfie de arquivos "slurping". É quando você lê o arquivo inteiro na memória de uma só vez.
O problema é que ele não escala bem. Você pode desenvolver código com um arquivo de tamanho razoável, colocá-lo em produção e de repente descobrir que está tentando ler arquivos medidos em gigabytes, e seu host está congelando ao tentar ler e alocar memória.
A E / S linha a linha é muito rápida e quase sempre tão eficaz quanto o slurping. É surpreendentemente rápido, na verdade.
Eu gosto de usar:
ou
O arquivo é herdado do IO e
foreach
está no IO, para que você possa usá-lo.Eu tenho alguns benchmarks mostrando o impacto de tentar ler arquivos grandes por meio de
read
E / S linha a linha em " Por que" compactar "um arquivo não é uma boa prática? ".fonte
Você pode ler o arquivo de uma só vez:
Quando o arquivo é grande, ou pode ser grande, geralmente é melhor processá-lo linha por linha:
Às vezes, você deseja acessar o identificador de arquivo ou controlar as leituras:
No caso de arquivos binários, você pode especificar um separador nulo e um tamanho de bloco, assim:
Finalmente, você pode fazer isso sem um bloco, por exemplo, ao processar vários arquivos simultaneamente. Nesse caso, o arquivo deve ser explicitamente fechado (aprimorado conforme o comentário de @antinome):
Referências: API do arquivo e a API do IO .
fonte
for_each
no arquivo ou no IO. Use emforeach
vez disso.while
vez deloop
e usandoensure
para garantir que o arquivo seja fechado, mesmo que uma exceção seja gerada. Como este (substitua ponto e vírgula com novas linhas):begin; f = File.open('testfile'); while line = f.gets; puts line; end; ensure; f.close; end
.Um método simples é usar
readlines
:Cada linha no arquivo de entrada será uma entrada na matriz. O método controla a abertura e o fechamento do arquivo para você.
fonte
read
qualquer outra variante, isso puxará o arquivo inteiro para a memória, o que pode causar grandes problemas se o arquivo for maior que a memória disponível. Além disso, por ser uma matriz, Ruby precisa criar a matriz, retardando o processo adicionalmente.http://www.ruby-doc.org/core-1.9.3/IO.html#method-c-read
fonte
Eu costumo fazer isso:
Isso fornecerá o texto inteiro como um objeto de string. Funciona apenas no Ruby 1.9.
fonte
retorna as últimas n linhas de your_file.log ou .txt
fonte
Uma maneira ainda mais eficiente é fazer o streaming solicitando ao kernel do sistema operacional que abra um arquivo e, em seguida, leia os bytes bit a bit. Ao ler um arquivo por linha no Ruby, os dados são retirados do arquivo 512 bytes por vez e divididos em "linhas" depois disso.
Ao armazenar em buffer o conteúdo do arquivo, o número de chamadas de E / S é reduzido ao dividir o arquivo em blocos lógicos.
Exemplo:
Adicione esta classe ao seu aplicativo como um objeto de serviço:
Chame-o e passe ao
:each
método um bloco:Leia sobre isso aqui neste post detalhado:
Arquivos Ruby Magic Slurping & Streaming por AppSignal
fonte
Eu acho que esse método é o mais "incomum". Talvez seja meio complicado, mas funciona se
cat
estiver instalado.fonte
content = File.read(filename)