Estou tentando anexar uma seqüência de caracteres a um arquivo de log. No entanto, o writeFile apagará o conteúdo todas as vezes antes de escrever a string.
fs.writeFile('log.txt', 'Hello Node', function (err) {
if (err) throw err;
console.log('It\'s saved!');
}); // => message.txt erased, contains only 'Hello Node'
Alguma idéia de como fazer isso da maneira mais fácil?
process.exit()
logo a seguirfs.appendFile
, poderá sair antes que a saída seja enviada. (Usandoreturn
é fina.)appendFileSync
,. nodejs.org/api/… Mas você pode perder um dos grandes benefícios do Node, que é as operações assíncronas. Certifique-se de capturar erros. Talvez em alguns sistemas operacionais, você possa ter acesso negado se solicitar o identificador de arquivo ao mesmo tempo. Não tenho certeza sobre isso.Quando você deseja gravar em um arquivo de log, ou seja, anexando dados ao final de um arquivo, nunca use
appendFile
.appendFile
abre um identificador de arquivo para cada dado que você adiciona ao seu arquivo, após um tempo você recebe umEMFILE
erro bonito .Posso acrescentar que
appendFile
não é mais fácil de usar do que aWriteStream
.Exemplo com
appendFile
:Até 8000 no meu computador, você pode anexar dados ao arquivo e obter o seguinte:
Além disso,
appendFile
gravará quando estiver ativado, para que seus logs não sejam gravados com carimbo de data e hora. Você pode testar, por exemplo, definir 1000 no lugar de 100000, a ordem será aleatória, depende do acesso ao arquivo.Se você deseja anexar a um arquivo, deve usar um fluxo gravável como este:
Você termina quando quiser. Você nem precisa usar
stream.end()
, a opção padrão é queAutoClose:true
, assim, seu arquivo será encerrado quando seu processo terminar e você evitará abrir muitos arquivos.fonte
stream.end()
antes dostream.write()
, portanto, não devemos usarstream.end()
, também como você mencionou queAutoClose:True
é uma opção padrão, por que se preocupar em escrever uma linha que não seja usar.due to asynchronous nature of Javascript
... O que? Array.forEach é uma operação síncrona. JS é síncrono. Apenas fornece algumas maneiras de gerenciar operações assíncronas, como Promises e async / waitit.fs.appendFile
resulta em muitos arquivos abertos porque você o executa de maneira assíncrona (você está criando assincronamente 10000 arquivos), acreditoappendFileSync
que não teria problema semelhante, também nãofs.appendFile
com intervalo adequado (1s provavelmente é mais do que suficiente) ou na fila.Seu código usando createWriteStream cria um descritor de arquivo para cada gravação. log.end é melhor porque pede que o nó feche imediatamente após a gravação.
fonte
var fs = require('graceful-fs')
, que solucionou alguns problemas conhecidos. Veja os documentos para mais informações.fs.createWriteStream
, useflags
. Se você estiver usando,fs.writeFile
então éflag
. Consulte Nó JS Docs - Sistema de arquivos para obter mais informações.Além disso
appendFile
, você também pode passar uma bandeirawriteFile
para acrescentar dados a um arquivo existente.Ao passar o sinalizador 'a', os dados serão anexados no final do arquivo.
fonte
fs.createWriteStream
, useflags
. Se você estiver usando,fs.writeFile
então éflag
. Consulte Nó JS Docs - Sistema de arquivos para obter mais informações.Você precisa abri-lo e depois escrever nele.
Aqui estão alguns links que ajudarão a explicar os parâmetros
abrir
escrever
fechar
EDIT : esta resposta não é mais válida, procure o novo método fs.appendFile para anexar.
fonte
O Node.js 0.8 possui
fs.appendFile
:Documentação
fonte
fonte
Se você deseja uma maneira fácil e sem estresse de escrever registros linha por linha em um arquivo, recomendo o fs-extra :
Testado com o nó v8.9.4.
fonte
Minha abordagem é bastante especial. Basicamente, uso a
WriteStream
solução, mas sem 'fechar' o fd usandostream.end()
. Em vez disso, eu usocork
/uncork
. Isso tem o benefício do baixo uso de RAM (se isso for importante para alguém) e acredito que é mais seguro usar para log / gravação (meu caso de uso original).A seguir, é apresentado um exemplo bastante simples. Observe que acabei de adicionar um
for
loop pseudo para showcase - no código de produção, estou aguardando mensagens do websocket.uncork
liberará os dados para o arquivo no próximo tick.No meu cenário, existem picos de até ~ 200 gravações por segundo em vários tamanhos. Durante a noite, porém, são necessárias apenas algumas gravações por minuto. O código está funcionando super confiável mesmo nos horários de pico.
fonte
Eu ofereço essa sugestão apenas porque o controle sobre os sinalizadores abertos às vezes é útil; por exemplo, você pode truncar primeiro um arquivo existente e depois anexar uma série de gravações a ele - nesse caso, use o sinalizador 'w' ao abrir o arquivo e não feche até que todas as gravações estejam concluídas. É claro que appendFile pode ser o que você procura :-)
fonte
Usando o pacote jfile :
fonte
Usar
fs.appendFile
oufsPromises.appendFile
são as opções mais rápidas e robustas quando você precisa acrescentar algo a um arquivo.Ao contrário de algumas das respostas sugeridas, se o caminho do arquivo é fornecido para a
appendFile
função, ele realmente fecha sozinho . Somente quando você passa um identificador de arquivo que obtém algo comofs.open()
você precisa cuidar para fechá-lo.Eu tentei com mais de 50.000 linhas em um arquivo.
Exemplos :
Ref: https://github.com/nodejs/node/issues/7560
Exemplo de execução: https://github.com/apickjs/apickFS/blob/master/writeLines.js
fonte
Aqui está um script completo. Preencha os nomes dos arquivos e execute-os e ele deve funcionar! Aqui está um tutorial em vídeo sobre a lógica por trás do script.
fonte
uma maneira mais fácil de fazer isso é
fonte
appendFileSync
solução?fonte
Além da resposta da denysonique , às vezes
appendFile
são utilizados tipos assíncronos e outros métodos assíncronos no NodeJS, nos quais a promessa retorna em vez da passagem de retorno de chamada. Para isso, é necessário agrupar a função compromisify
HOF ou importar funções assíncronas do namespace promises:Espero que ajude 😉
fonte