Escribir archivos en Node.js

1851

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

0
2727

Hay muchos detalles en la API del sistema de archivos . 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!");
}); 

// Or
fs.writeFileSync('/tmp/test-sync', 'Hey there!');
14
  • 32
    Probé este script usando Node e intenté cambiar la ruta del archivo a "/ home /", pero recibí el siguiente error: { [Error: EACCES, open '/home/test.txt'] errno: 3, code: 'EACCES', path: '/home/test.txt' } ¿Cómo puedo modificar este script para que funcione fuera de él /tmp? 10/09/12 a las 20:37
  • 143
    También tenga en cuenta que puede usar fs.writeFileSync (...) para lograr lo mismo sincrónicamente. 23/01/2013 a las 18:28
  • 8
    Tal vez sea un poco antiguo, pero @AndersonGreen, debe ejecutar el nodo como root o chmod / home correctamente para permitir permisos de R / W al propietario actual del proceso del nodo (su nombre de usuario es difícil) para que pueda escribir el archivo 2 de enero de 2014 a las 23:34
  • 43
    En realidad, @DenysVitali, el problema es que Jane no debería poder escribir ningún archivo en /home/.... Generalmente ese directorio es 755 root: wheel (o lo que sea). Si el nodo quiere escribir un archivo como jane, será más fácil escribir en él /home/jane/test.txt. Cambiar /homea algo más permisivo que 755 es un gran error. 26/01/2014 a las 23:05
  • 11
    @JaneAvriette Bueno, como quería guardar el archivo en el /homedirectorio, le sugerí que lo modificara. Sé que podría generar un problema de seguridad. Pero bueno, si el usuario quiere guardar allí, esa es la solución. PD: estoy de acuerdo con lo que dijiste (: 29/01/2014 a las 22:51
575

Actualmente hay tres formas de escribir un archivo:

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

    Debe esperar la devolución de llamada para asegurarse de que el búfer esté escrito en el disco. No está almacenado en búfer.

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

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

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

    Crea un WriteStream, que es conveniente porque no necesita esperar una devolución de llamada. Pero, de nuevo, no está almacenado en búfer.

A WriteStream, como su nombre lo dice, es una corriente. Un flujo por definición es "un búfer" que contiene datos que se mueven en una dirección (origen ► destino). Pero una transmisión en la que se puede escribir no está necesariamente "almacenada en búfer". Un flujo se "almacena en búfer" cuando escribe nveces y, en ese momento n+1, el flujo envía el búfer al núcleo (porque está lleno y debe vaciarse).

En otras palabras: "Un búfer" es el objeto. Si está “almacenado en búfer” o no es una propiedad de ese objeto.

Si observa el código, WriteStreamhereda de un Streamobjeto grabable . Si prestas atención, verás cómo eliminan el contenido; no tienen ningún sistema de almacenamiento intermedio.

Si escribe una cadena, se convierte en un búfer y luego se envía a la capa nativa y se escribe en el disco. Al escribir cadenas, no llenan ningún búfer. Entonces, si lo hace:

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

Estás haciendo:

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

Son tres llamadas a la capa de E / S. Aunque está utilizando "búferes", los datos no se almacenan en búfer. Un flujo almacenado en búfer 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 admite dos funciones: cork()y uncork(). Parece que estas funciones finalmente le permitirán almacenar en búfer / vaciar las llamadas de escritura.

Por ejemplo, en Java hay algunas clases que proporcionan flujos almacenados en búfer ( BufferedOutputStream, BufferedWriter...). Si escribe tres bytes, estos bytes se almacenarán en el búfer (memoria) en lugar de realizar una llamada de E / S solo por tres bytes. Cuando el búfer está lleno, el contenido se vacía y se guarda en el disco. Esto mejora el rendimiento.

No estoy descubriendo nada, solo estoy recordando cómo se debe hacer un acceso al disco.

6
  • 6
    +1 - bonita explicación. Para el flujo de escritura, es importante leer los documentos detenidamente. Si devuelve falso o cerrando, es importante llamar a writer.once ('drenaje', función () {}) o perdí líneas que no se habían agotado cuando finalizó el proceso. 19/06/2014 a las 15:18
  • 4
    ¿Alguna posibilidad de que pueda proporcionar un ejemplo de cómo usar cork()y uncork()para aquellos de nosotros que queremos probar el nodo 0.11 de prelanzamiento? 16 de agosto de 2014 a las 7:05
  • A partir de ahora, Node v0.12 es estable.
    aug
    1 de abril de 2015 a las 5:41
  • Según un análisis de código de GitHub, fs.writeFile parece ser la más popular de las funciones que mencionaste. Aquí hay ejemplos del mundo real para usar fs.writeFile
    drorw
    18/04/19 a las 20:11
  • 1
    ¿Existen bibliotecas de calidad de producción sobre la npmimplementación de escritura almacenada en búfer? 12 de mayo de 2019 a las 18:48
288

Por supuesto, puede hacerlo un poco más avanzado. Sin bloqueo, escribiendo bits y piezas, sin 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();
});
9
  • 21
    ¿Cuál es la variable 'fd' que se pasa a la devolución de llamada para stream.once? 18/10/12 a las 5:49
  • 2
    @ScottDavidTesler descriptor de archivo para que pueda cerrar la transmisión una vez que haya terminado. 20/11/12 a las 11:32
  • 3
    ¿Cuándo cierro la corriente? ¿Por qué esto es sin bloqueo? Solo por curiosidad, estoy tratando de escribir en un archivo de registro. 3 de enero de 2013 a las 3:06
  • 1
    No estoy seguro si cuando la corriente se descarga. Supongo que existe la posibilidad de descargar la transmisión a pedido. 24/04/2013 a las 9:38
  • 1
    @JoLiss Tendrás que esperar. 12/11/2014 a las 15:37
83

Escritura sincrónica

fs.writeFileSync(file, data[, options])

fs = require('fs');

fs.writeFileSync("foo.txt", "bar");

Escritura asincrónica

fs.writeFile(file, data[, options], callback)

fs = require('fs');

fs.writeFile('foo.txt', 'bar', (err) => { if (err) throw err; });

Dónde

file <string> | <Buffer> | <URL> | <integer> filename or file descriptor
data <string> | <Buffer> | <Uint8Array>
options <Object> | <string>
callback <Function>

Vale la pena leer el archivo oficial del sistema (fs) docs .

Actualización: async / await

fs = require('fs');
util = require('util');
writeFile = util.promisify(fs.writeFile);

fn = async () => { await writeFile('foo.txt', 'bar'); }

fn()
58
var path = 'public/uploads/file.txt',
buffer = new Buffer("some content\n");

fs.open(path, 'w', function(err, fd) {
    if (err) {
        throw 'error opening file: ' + err;
    }

    fs.write(fd, buffer, 0, buffer.length, null, function(err) {
        if (err) throw 'error writing file: ' + err;
        fs.close(fd, function() {
            console.log('file written');
        })
    });
});
2
  • 2
    esto demuestra cómo escribir un archivo usando operaciones fs de nivel inferior. por ejemplo, puede garantizar que el archivo haya terminado de grabarse en el disco y haya liberado los descriptores de archivo. 18 de enero de 2015 a las 17:30
  • Dado que en este ejemplo el desplazamiento se establece en '0' (= tercer parámetro de fs.write()), este ejemplo solo funciona si todo es lo suficientemente corto como para ser escrito en una sola llamada de escritura.
    Manfred
    9 feb.20 a las 20:14
38

Las respuestas proporcionadas están fechadas y una forma más nueva de hacerlo es:

const fsPromises = require('fs').promises
await fsPromises.writeFile('/path/to/file.txt', 'data to write')

consulte los documentos aquí para obtener más información

7
  • 1
    (node:23759) ExperimentalWarning: The fs.promises API is experimental
    jgraup
    29/04/19 a las 18:49
  • @jgraup: ¿estás usando la última versión de node? 30 de abril de 2019 a las 3:11
  • Nodo v10.15.0
    jgraup
    30 de abril de 2019 a las 3:23
  • 9
    La función de cierre tiene que ser asíncrona o no funcionará.
    Zimano
    29/08/19 a las 12:28
  • 1
    @Zimano Node ya tiene soporte para espera de nivel superior, no necesita un contenedor asíncrono. 26 abr.20 a las 6:24
35

Me gustó Index of ./articles/file-system .

Funcionó para mí.

Consulte también ¿Cómo escribo archivos en node.js? .

fs = require('fs');
fs.writeFile('helloworld.txt', 'Hello World!', function (err) {
    if (err) 
        return console.log(err);
    console.log('Wrote Hello World in file helloworld.txt, just check it');
});

Contenido de helloworld.txt:

Hello World!

Actualización:
como en el nodo de Linux se escribe en el directorio actual, parece que en algunos otros no lo hacen, así que agrego este comentario por si acaso:
Usar esto ROOT_APP_PATH = fs.realpathSync('.'); console.log(ROOT_APP_PATH);para llegar a donde está escrito el archivo.

5
  • ¿Dónde encontrar el archivo helloworld.txt? No puedo encontrarlo en ninguna carpeta ... gracias. 19 de diciembre de 2014 a las 6:58
  • en la carpeta que ejecuta el script
    Sérgio
    19/12/2014 a las 17:22
  • Eso es raro ... No puedo encontrarlo por ningún lado. ¿Estará escondido? gracias de nuevo ~ 19/12/2014 a las 21:51
  • 6
    Lo acabo de encontrar. Usando este ROOT_APP_PATH = fs.realpathSync ('.'); console.log ( ROOT_APP_PATH ); para obtener mi dónde está escrito el archivo. Gracias. 22 de diciembre de 2014 a las 6:21
  • @ Sérgio: ¿necesitamos cerrar el archivo de escritura? Estoy llamando a otro proceso y recibo un mensaje de error con respecto al archivo que comienza a ser utilizado por algún otro proceso.
    Amir
    19/12/18 a las 16:49
25

Sé que la pregunta sobre "escribir", pero en un sentido más general, "agregar" puede ser útil en algunos casos, ya que es fácil de usar en un bucle para agregar texto a un archivo (ya sea que el archivo exista o no). Utilice "\ n" si desea agregar líneas, por ejemplo:

var fs = require('fs');
for (var i=0; i<10; i++){
    fs.appendFileSync("junk.csv", "Line:"+i+"\n");
}
1
  • 1
    Dado que ahora está disponible, recomiendo usarlo en constlugar de var, es decir const fs = require('fs');, para evitar efectos secundarios no deseados, en particular si está trabajando con una base de código algo más grande.
    Manfred
    9 feb.20 a las 22:58
14

De acuerdo, es bastante simple ya que Node tiene una funcionalidad incorporada para esto, se llama fsque significa Sistema de archivos y básicamente, módulo del Sistema de archivos NodeJS ...

Así que primero solicítelo en su archivo server.js como este:

var fs = require('fs');

fstiene pocos métodos para escribir en el archivo, pero mi forma preferida es usar appendFile, esto agregará las cosas al archivo y, si el archivo no existe, creará uno, el código podría ser como el siguiente:

fs.appendFile('myFile.txt', 'Hi Ali!', function (err) {
  if (err) throw err;
  console.log('Thanks, It\'s saved to the file!');
});
1
  • 3
    las comillas simples en la cadena deben escaparse.
    Tamer
    28/03/19 a las 13:08
13

Puede escribir en un archivo usando el módulo fs (sistema de archivos).

A continuación, se muestra un ejemplo de cómo puede hacerlo:

const fs = require('fs');

const writeToFile = (fileName, callback) => {
  fs.open(fileName, 'wx', (error, fileDescriptor) => {
    if (!error && fileDescriptor) {
      // Do something with the file here ...
      fs.writeFile(fileDescriptor, newData, (error) => {
        if (!error) {
          fs.close(fileDescriptor, (error) => {
            if (!error) {
              callback(false);
            } else {
              callback('Error closing the file');
            }
          });
        } else {
          callback('Error writing to new file');
        }
      });
    } else {
      callback('Could not create new file, it may already exists');
    }
  });
};

También es posible que desee deshacerse de esta estructura de código de devolución de llamada dentro de la devolución de llamada mediante el uso de promesas y declaraciones async/ await. Esto hará que la estructura del código asincrónico sea mucho más plana. Para hacer eso, se puede utilizar una útil función util.promisify (original) . Nos permite pasar de las devoluciones de llamada a las promesas. Eche un vistazo al ejemplo con fsfunciones a continuación:

// Dependencies.
const util = require('util');
const fs = require('fs');

// Promisify "error-back" functions.
const fsOpen = util.promisify(fs.open);
const fsWrite = util.promisify(fs.writeFile);
const fsClose = util.promisify(fs.close);

// Now we may create 'async' function with 'await's.
async function doSomethingWithFile(fileName) {
  const fileDescriptor = await fsOpen(fileName, 'wx');

  // Do something with the file here...

  await fsWrite(fileDescriptor, newData);
  await fsClose(fileDescriptor);
}
3
  • 1
    ¿Por qué son estos fragmentos y no fragmentos de código? De todos modos, nunca podrán ejecutarse en un navegador.
    Zimano
    29/08/19 a las 13:46
  • @Zimano Según tengo entendido, la pregunta era sobre nodejs, por lo que no es necesario que se pueda ejecutar en un navegador.
    Manfred
    9 feb.20 a las 23:01
  • 1
    @Manfred ¡Exactamente! Creo que entendiste mal lo que estaba tratando de decir; ¡No tiene sentido tener fragmentos ya que es nodejs!
    Zimano
    11/02/20 a las 10:31
11
 var fs = require('fs');
 fs.writeFile(path + "\\message.txt", "Hello", function(err){
 if (err) throw err;
  console.log("success");
}); 

Por ejemplo: leer archivo y escribir en otro archivo:

  var fs = require('fs');
    var path = process.cwd();
    fs.readFile(path+"\\from.txt",function(err,data)
                {
                    if(err)
                        console.log(err)
                    else
                        {
                            fs.writeFile(path+"\\to.text",function(erro){
                                if(erro)
                                    console.log("error : "+erro);
                                else
                                    console.log("success");
                            });
                        }
                });
2
  • ¿Dónde está escribiendo los datos en el "to.text"? 18 de mayo de 2017 a las 9:09
  • ¿Qué agrega esta respuesta a las múltiples respuestas ya existentes writeFile? 23/10/19 a las 10:37
11

Aquí usamos w + para leer / escribir ambas acciones y si no se encuentra la ruta del archivo, se creará automáticamente.

fs.open(path, 'w+', function(err, data) {
    if (err) {
        console.log("ERROR !! " + err);
    } else {
        fs.write(data, 'content', 0, 'content length', null, function(err) {
            if (err)
                console.log("ERROR !! " + err);
            fs.close(data, function() {
                console.log('written success');
            })
        });
    }
});

Contenido significa lo que tiene que escribir en el archivo y su longitud, 'content.length'.

6

Aquí está el ejemplo de cómo leer el archivo csv desde local y escribir el archivo csv en local.

var csvjson = require('csvjson'),
    fs = require('fs'),
    mongodb = require('mongodb'),
    MongoClient = mongodb.MongoClient,
    mongoDSN = 'mongodb://localhost:27017/test',
    collection;

function uploadcsvModule(){
    var data = fs.readFileSync( '/home/limitless/Downloads/orders_sample.csv', { encoding : 'utf8'});
    var importOptions = {
        delimiter : ',', // optional 
        quote     : '"' // optional 
    },ExportOptions = {
        delimiter   : ",",
        wrap        : false
    }
    var myobj = csvjson.toSchemaObject(data, importOptions)
    var exportArr = [], importArr = [];
    myobj.forEach(d=>{
        if(d.orderId==undefined || d.orderId=='') {
            exportArr.push(d)
        } else {
            importArr.push(d)
        }
    })
    var csv = csvjson.toCSV(exportArr, ExportOptions);
    MongoClient.connect(mongoDSN, function(error, db) {
        collection = db.collection("orders")
        collection.insertMany(importArr, function(err,result){
            fs.writeFile('/home/limitless/Downloads/orders_sample1.csv', csv, { encoding : 'utf8'});
            db.close();
        });            
    })
}

uploadcsvModule()
1
  • 1
    Esto introduce todo tipo de complicaciones (MongoClient, JSON, etc.) que no pertenecen a la pregunta. 23/10/19 a las 10:35
6

fs.createWriteStream(path[,options])

options may also include a start option to allow writing data at some position past the beginning of the file. Modifying a file rather than replacing it may require a flags mode of r+ rather than the default mode w. The encoding can be any one of those accepted by Buffer.

If autoClose is set to true (default behavior) on 'error' or 'finish' the file descriptor will be closed automatically. If autoClose is false, then the file descriptor won't be closed, even if there's an error. It is the application's responsibility to close it and make sure there's no file descriptor leak.

Like ReadStream, if fd is specified, WriteStream will ignore the path argument and will use the specified file descriptor. This means that no 'open' event will be emitted. fd should be blocking; non-blocking fds should be passed to net.Socket.

If options is a string, then it specifies the encoding.

Después, leyendo este largo artículo. Debes entender cómo funciona. Entonces, aquí hay un ejemplo de createWriteStream().

/* The fs.createWriteStream() returns an (WritableStream {aka} internal.Writeable) and we want the encoding as 'utf'-8 */
/* The WriteableStream has the method write() */
fs.createWriteStream('out.txt', 'utf-8')
.write('hello world');
1
3

Puedes usar la biblioteca easy-file-manager

instalar primero desde npm npm install easy-file-manager

Muestra para cargar y eliminar archivos

var filemanager = require('easy-file-manager')
var path = "/public"
var filename = "test.jpg"
var data; // buffered image

filemanager.upload(path,filename,data,function(err){
    if (err) console.log(err);
});

filemanager.remove(path,"aa,filename,function(isSuccess){
    if (err) console.log(err);
});
1
  • 2
    This modules is created to save and remove files.. No es una respuesta.
    Green
    9/10/2016 a las 9:38
3

Puede escribir en archivos con secuencias.

Solo hazlo así:

const fs = require('fs');

const stream = fs.createWriteStream('./test.txt');
stream.write("Example text");
1

Punto 1:

Si desea escribir algo en un archivo. significa: eliminará todo lo que ya esté guardado en el archivo y escribirá el nuevo contenido. use fs.promises.writeFile ()

Punto 2:

Si desea agregar algo a un archivo. significa: no eliminará nada ya guardado en el archivo, sino que agregará el nuevo elemento en el contenido del archivo. Luego, primero lea el archivo y luego agregue el contenido en el valor legible, luego escríbalo en el archivo. así que use fs.promises.readFile y fs.promises.writeFile ()


ejemplo 1: quiero escribir un objeto JSON en mi archivo JSON.

const fs = require('fs');
writeFile  ('./my_data.json' , {id:1, name:'my name'} )
async function writeFile  (filename ,writedata) {
    try {
        await fs.promises.writeFile(filename, JSON.stringify(writedata,null, 4), 'utf8');
       console.log ('data is written successfully in the file')
    }
    catch(err) {
        console.log ('not able to write data in the file ')
    }
}

ejemplo2: si desea agregar datos a un archivo JSON. desea agregar datos {id: 1, name: 'my name'} al archivo my_data.json en la misma carpeta raíz. simplemente llame a la función append_data (file_path, data) .

Agregará datos en el archivo JSON si el archivo existía. o creará el archivo y le agregará los datos.

   const fs = require('fs');
   data = {id:1, name:'my name'}
   file_path = './my_data.json'
   append_data (file_path , data )

   async function append_data (filename , data ) {

      if (fs.existsSync(filename)) {
         read_data = await readFile(filename)
         if (read_data == false) {
             console.log('not able to read file')
         }
         else {
             read_data.push(data)
             dataWrittenStatus = await writeFile(filename, read_data)
             if dataWrittenStatus == true {
               console.log('data added successfully')
             }
            else{
               console.log('data adding failed')
            }
        }
       else{
          dataWrittenStatus = await writeFile(filename, [data])
          if dataWrittenStatus == true {
             console.log('data added successfully')
          }
          else{
             console.log('data adding failed')
          }
      }
   }



async function readFile  (filePath) {
  try {
    const data = await fs.promises.readFile(filePath, 'utf8')
    return JSON.parse(data)
  }
 catch(err) {
     return false;
  }
}

async function writeFile  (filename ,writedata) {
  try {
      await fs.promises.writeFile(filename, JSON.stringify(writedata,null, 4), 'utf8');
      return true
  }
  catch(err) {
      return false
  }
}
0

Punto 1:

Si desea escribir algo en un archivo. significa: eliminará todo lo que ya esté guardado en el archivo y escribirá el nuevo contenido. use fs.promises.writeFile ()

Punto 2:

Si desea agregar algo a un archivo. significa: no eliminará nada ya guardado en el archivo, sino que agregará el nuevo elemento en el contenido del archivo. Luego, primero lea el archivo y luego agregue el contenido en el valor legible, luego escríbalo en el archivo. así que use fs.promises.readFile y fs.promises.writeFile ()


ejemplo 1: quiero escribir un objeto JSON en mi archivo JSON.

const fs = require('fs');

writeFile (nombre de archivo, writedata) función asíncrona writeFile (nombre de archivo, writedata) {try {await fs.promises.writeFile (nombre de archivo, JSON.stringify (writedata, null, 4), 'utf8'); return true} catch (err) {return false}}

-1

Puede escribir en un archivo con el siguiente ejemplo de código:

var data = [{ 'test': '123', 'test2': 'Lorem Ipsem ' }];
fs.open(datapath + '/data/topplayers.json', 'wx', function (error, fileDescriptor) {
  if (!error && fileDescriptor) {
    var stringData = JSON.stringify(data);
    fs.writeFile(fileDescriptor, stringData, function (error) {
      if (!error) {
        fs.close(fileDescriptor, function (error) {
          if (!error) {
            callback(false);
          } else {
            callback('Error in close file');
          }
        });
      } else {
        callback('Error in writing file.');
      }
    });
  }
});
2
  • 1
    writeFileya se había dado como respuesta varias veces, hace años. ¿Qué agrega esta respuesta? 23/10/19 a las 10:39
  • Además, ¿por qué abres el archivo? ¿No debería ser la respuesta escribir archivos?
    Michal
    5 de ene. De 2020 a las 22:23