Escribir archivos en Node.js

1646

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

Gjorgji
fuente

Respuestas:

2466

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!');
Brian McKenna
fuente
26
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 /tmp?
Anderson Green
130
También tenga en cuenta que puede usar fs.writeFileSync (...) para lograr lo mismo sincrónicamente.
David Erwin el
77
Tal vez sea un poco viejo, pero @AndersonGreen, debe ejecutar el nodo como root o chmod / home correctamente para permitir permisos R / W al propietario del proceso del nodo actual (su nombre de usuario es difícil) para que pueda escribir el archivo
Denys Vitali
39
En realidad, @DenysVitali, el problema es que Jane no debería poder escribir ningún archivo /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.
jane arc
77
@JaneAvriette Bueno, como quería guardar el archivo en el /homedirectorio, sugerí cambiarlo. Sé que podría generar un problema de seguridad. Pero bueno, si el usuario quiere ahorrar allí, esa es la solución. PD: Estoy de acuerdo con lo que dijiste (:
Denys Vitali
537

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 se escriba en el disco. No está protegido.

  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á protegido.

A WriteStream, como su nombre lo dice, es una corriente. Una secuencia, por definición, es "un búfer" que contiene datos que se mueven en una dirección (origen ► destino). Pero una secuencia de escritura no está necesariamente "almacenada". Una secuencia se “almacena en búfer” cuando escribe ntiempos, y en ese momento n+1, la secuencia envía el búfer al núcleo (porque está lleno y necesita ser vaciado).

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

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

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 están llenando ningún búfer. Entonces, si lo haces:

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 "buffers", los datos no están almacenados. Una secuencia almacenada 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/02/2015) ahora admite dos funciones: cork()y uncork(). Parece que estas funciones finalmente le permitirán almacenar / borrar las llamadas de escritura.

Por ejemplo, en Java hay algunas clases que proporcionan secuencias almacenadas en búfer ( BufferedOutputStream, BufferedWriter...). Si escribe tres bytes, estos bytes se almacenarán en el búfer (memoria) en lugar de hacer 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 descubro nada, solo recuerdo cómo se debe hacer un acceso al disco.

Gabriel Llamas
fuente
55
+1 - buena explicación. Para la secuencia de escritura, es importante leer los documentos con cuidado. Si devuelve falso o de cierre, es importante llamar a writer.once ('drenaje', función () {}) o perdí líneas que no se habían drenado cuando finalizó el proceso.
bryanmac
44
¿Hay alguna posibilidad de que pueda proporcionar un ejemplo de cómo usar cork()y uncork()para aquellos de nosotros que queremos probar el nodo de pre-lanzamiento 0.11?
professormeowingtons
A partir de ahora, el nodo v0.12 es estable.
agosto
Según un análisis de código de GitHub, fs.writeFile parece ser la más popular de las funciones que mencionó. Aquí hay ejemplos del mundo real para usar fs.writeFile
drorw
¿Existen bibliotecas de calidad de producción en la npmimplementación de la escritura en búfer?
nponeccop
266

Por supuesto, puedes hacerlo un poco más avanzado. Sin bloqueo, escribiendo bits y piezas, no escribiendo 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();
});
Fredrik Andersson
fuente
17
¿Cuál es la variable 'fd' que se pasa a la devolución de llamada para stream.once?
Scott Tesler el
1
Descriptor de archivo @ScottDavidTesler para que pueda cerrar la transmisión una vez que haya terminado con ella.
Alexey Kamenskiy
3
¿Cuándo cierro la transmisión? ¿Por qué es esto sin bloqueo? Por curiosidad, estoy tratando de escribir en un archivo de registro.
MetaGuru
1
No estoy seguro de cuándo se descarga la corriente. Mi conjetura es que existe la posibilidad de vaciar el flujo a pedido.
Fredrik Andersson
1
@JoLiss Tendrás que esperarlo.
Fredrik Andersson
61

Escritura Sincrónica

fs.writeFileSync (archivo, datos [, opciones])

fs = require('fs');

fs.writeFileSync("synchronous.txt", "synchronous write!")

Escritura asincrónica

fs.writeFile (archivo, datos [, opciones], devolución de llamada)

fs = require('fs');

fs.writeFile('asynchronous.txt', 'asynchronous write!', (err) => {
  if (err) throw err;
  console.log('The file has been saved!');
});

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 .

Moriarty
fuente
53
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');
        })
    });
});
Señor P
fuente
2
esto demuestra cómo escribir un archivo usando operaciones fs de nivel inferior. por ejemplo, puede garantizar cuando el archivo haya terminado de escribirse en el disco y haya publicado descriptores de archivo.
Sean Glover
Dado que en este ejemplo, el desplazamiento si se establece en '0' (= tercer parámetro de fs.write()) este ejemplo solo funciona si todo es lo suficientemente corto como para escribirse en una sola llamada de escritura.
Manfred
31

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

Funcionó para mi.

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:
Al igual que en el nodo de Linux, escriba en el directorio actual, parece que en otros no, así que agrego este comentario por si acaso:
Utilizando esto ROOT_APP_PATH = fs.realpathSync('.'); console.log(ROOT_APP_PATH);para llegar a donde se escribe el archivo.

Sergio
fuente
¿Dónde encontrar el archivo helloworld.txt? No puedo encontrarlo en ninguna carpeta ... gracias.
Kai Feng Chew
en la carpeta en la que ejecuta el script
Sérgio
Eso es raro ... simplemente no puedo encontrarlo en ningún lado. ¿Estará oculto? gracias de nuevo ~
Kai Feng Chew
66
Lo acabo de encontrar. Usando este ROOT_APP_PATH = fs.realpathSync ('.'); console.log ( ROOT_APP_PATH ); para llegar a donde está escrito el archivo. Gracias.
Kai Feng Chew
@ Sergio: ¿necesitamos cerrar el archivo de escritura? Estoy llamando a otro proceso y recibo un mensaje de error con respecto al archivo que otro proceso comienza a utilizar.
Amir
24

Las respuestas proporcionadas son anticuadas y una nueva forma de hacerlo es:

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

ver documentos aquí para más información

TrevTheDev
fuente
1
(node:23759) ExperimentalWarning: The fs.promises API is experimental
jgraup
@jgraup: ¿estás usando la última versión del nodo?
TrevTheDev
Nodov10.15.0
jgraup
77
La función de cierre debe ser asíncrona o no funcionará.
Zimano
1
@wintercounter ¡Eso es muy dulce!
Zimano
20

Sé que la pregunta sobre "escribir", pero en un sentido más general, "agregar" podría 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 un "\ 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");
}
Astra Bear
fuente
Como ahora está disponible, recomendaría usar 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
11

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

Así que primero pídalo 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 usarlo appendFile, esto agregará las cosas al archivo y si el archivo no existe, creará uno, el código podría ser el siguiente:

fs.appendFile('myFile.txt', 'Hi Ali!', function (err) {
  if (err) throw err;
  console.log('Thanks, It\'s saved to the file!');
});
Alireza
fuente
3
La comilla simple en la cadena se debe escapar.
Domador
9
 var fs = require('fs');
 fs.writeFile(path + "\\message.txt", "Hello", function(err){
 if (err) throw err;
  console.log("success");
}); 

Por ejemplo: leer el 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");
                            });
                        }
                });
Masoud Siahkali
fuente
¿Dónde está escribiendo los datos en el "to.text"?
Ravi Shanker Reddy
¿Qué agrega esta respuesta a las múltiples respuestas ya existentes writeFile?
Dan Dascalescu el
9

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

Aquí hay un ejemplo de cómo puedes 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 devolución de llamada utilizando Promesas y declaraciones async/ await. Esto hará que la estructura del código asíncrono sea mucho más plana. Para ello, se puede utilizar una útil función util.promisify (original) . Nos permite cambiar de devoluciones de llamada a promesas. Eche un vistazo al ejemplo con las 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);
}
Oleksii Trekhleb
fuente
1
¿Por qué son estos fragmentos y no fragmentos de código? De todos modos, nunca podrán ejecutarse en un navegador.
Zimano
@Zimano Según tengo entendido, la pregunta era con respecto a nodejs, por lo que no necesita poder ejecutarse en un navegador.
Manfred
1
@Manfred ¡Exactamente! Creo que entendiste mal lo que estaba tratando de decir; no tiene sentido tener fragmentos ya que es nodejs!
Zimano
5

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'.

Gunjan Patel
fuente
3

Aquí está la muestra 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()
KARTHIKEYAN.A
fuente
1
Esto introduce todo tipo de complicaciones (MongoClient, JSON, etc.) que no pertenecen a la pregunta.
Dan Dascalescu el
3

fs.createWriteStream(path[,options])

optionsTambién puede incluir una startopción para permitir la escritura de datos en alguna posición después del comienzo del archivo. Modificar un archivo en lugar de reemplazarlo puede requerir un flagsmodo en r+lugar del modo predeterminado w. La codificación puede ser cualquiera de las aceptadas por Buffer .

Si autoClosese establece en verdadero (comportamiento predeterminado) 'error'o 'finish'el descriptor de archivo se cerrará automáticamente. Si autoClosees falso, el descriptor de archivo no se cerrará, incluso si hay un error. Es responsabilidad de la aplicación cerrarla y asegurarse de que no haya fugas en el descriptor de archivo.

Como ReadStream , sifd se especifica, WriteStream ignorará el pathargumento y utilizará el descriptor de archivo especificado. Esto significa que no 'open'se emitirá ningún evento. fddebería estar bloqueando; los no bloqueantes se fddeben pasar a net.Socket .

Si optionses una cadena, entonces especifica la codificación.

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

/* 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');

fuente
createWriteStreamya se mencionó en múltiples respuestas años antes de esta.
Dan Dascalescu el
0

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);
});
Christoper
fuente
2
This modules is created to save and remove files.. No es una respuesta
Verde
-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.');
      }
    });
  }
});
Mudassir
fuente
1
writeFileya se había dado como respuesta varias veces, hace años. ¿Qué agrega esta respuesta?
Dan Dascalescu el
Además, ¿por qué abres el archivo? ¿No debería ser la respuesta sobre escribir archivos?
Michal