Escribir archivos en Node.js

He estado tratando de encontrar una manera de escribir en un archivo cuando se utiliza Node.js, pero sin éxito. ¿Cómo puedo hacerlo?

Solución

Hay muchos detalles en el File System API. La forma más común es:

const fs = require('fs');

fs.writeFile("/tmp/test", "Hey there!", function(err) {

    if(err) {
        return console.log(err);
    }

    console.log("The file was saved!");
}); 
Comentarios (16)

Actualmente hay tres formas de escribir un archivo:

  1. fs.write(fd, buffer, offset, length, position, callback)

    Hay que esperar a la llamada de retorno para asegurarse de que el buffer se escribe en el disco. No es un búfer.

  2. fs.writeFile(filename, data, [encoding], callback)

    Todos los datos deben almacenarse al mismo tiempo; no se pueden realizar escrituras secuenciales.

  3. fs.createWriteStream(path, [options])

    Crea un WriteStream, lo cual es conveniente porque no es necesario esperar una llamada de retorno. Pero, de nuevo, no se almacena en el buffer.

Un WriteStream, como su nombre indica, es un flujo. Un stream por definición es "un buffer" que contiene datos que se mueven en una dirección (origen ► destino). Pero un flujo con capacidad de escritura no es necesariamente un "buffer". Un flujo está "almacenado en un buffer" cuando escribes n veces, y en el momento n+1, el flujo envía el buffer al núcleo (porque está lleno y necesita ser vaciado).

En otras palabras: "Un buffer" es el objeto. El hecho de que "se almacene en el buffer" es una propiedad de ese objeto.

Si miras el código, el WriteStream hereda de un objeto Stream escribible. Si te fijas, verás cómo vacían el contenido; no tienen ningún sistema de buffering.

Si escribes una cadena, se convierte en un buffer, y luego se envía a la capa nativa y se escribe en el disco. Cuando se escriben cadenas, no se llena ningún búfer. Así que, si lo haces:

lenguaje-todo: lang-js -->

write("a")
write("b")
write("c")

Lo estás haciendo:

fs.write(new Buffer("a"))
fs.write(new Buffer("b"))
fs.write(new Buffer("c"))

Eso son tres llamadas a la capa de E/S. Aunque estás usando "buffers", los datos no están almacenados en un buffer. Un flujo con buffer haría: fs.write(new Buffer ("abc")), una llamada a la capa de E/S.

A partir de ahora, en Node.js v0.12 (versión estable anunciada el 02/06/2015) ahora soporta dos funciones: cork() y uncork(). Parece que estas funciones permitirán por fin amortiguar/descargar las llamadas de escritura.

Por ejemplo, en Java hay algunas clases que proporcionan flujos con buffer (BufferedOutputStream, BufferedWriter...). Si escribes tres bytes, estos bytes serán almacenados en el buffer (memoria) en lugar de hacer una llamada de E/S sólo para tres bytes. Cuando el buffer está lleno, el contenido se vacía y se guarda en el disco. Esto mejora el rendimiento.

No estoy descubriendo nada, sólo recordando cómo debe hacerse un acceso a disco.

Comentarios (5)

Por supuesto, puedes hacerlo un poco más avanzado. No bloquear, escribir trozos, no escribir todo el archivo a la vez:

var fs = require('fs');
var stream = fs.createWriteStream("my_file.txt");
stream.once('open', function(fd) {
  stream.write("My first row\n");
  stream.write("My second row\n");
  stream.end();
});
Comentarios (9)