Écriture de fichiers dans Node.js

1646

J'ai essayé de trouver un moyen d'écrire dans un fichier lors de l'utilisation de Node.js, mais sans succès. Comment puis je faire ça?

Gjorgji
la source

Réponses:

2466

Il y a beaucoup de détails dans l' API du système de fichiers . La manière la plus courante est:

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
la source
26
J'ai testé ce script en utilisant Node, et j'ai essayé de changer le chemin du fichier en "/ home /", mais j'ai eu l'erreur suivante: { [Error: EACCES, open '/home/test.txt'] errno: 3, code: 'EACCES', path: '/home/test.txt' } Comment puis-je modifier ce script pour qu'il fonctionne en dehors de /tmp?
Anderson Green
130
Notez également que vous pouvez utiliser fs.writeFileSync (...) pour accomplir la même chose de manière synchrone.
David Erwin
7
C'est peut-être un peu vieux, mais @AndersonGreen, vous devez exécuter le nœud en tant que root ou chmod / home correctement pour autoriser les autorisations R / W au propriétaire du processus de nœud actuel (votre nom d'utilisateur est difficile) afin que vous puissiez écrire le fichier
Denys Vitali
39
En fait, @DenysVitali, le problème est que jane ne devrait pas pouvoir écrire de fichiers /home/.... Généralement, ce répertoire est 755 root: wheel (ou autre). Si le nœud veut écrire un fichier en tant que jane, il sera plus facile d'y écrire /home/jane/test.txt. Changer /homepour quelque chose de plus permissif que 755 est une énorme erreur.
jane arc
7
@JaneAvriette Eh bien, comme il voulait enregistrer le fichier dans le /homerépertoire, j'ai suggéré de le modifier. Je sais que cela pourrait générer un problème de sécurité. Mais bon, si l'utilisateur veut y sauvegarder, c'est la solution. PS: je suis d'accord avec ce que vous avez dit (:
Denys Vitali
537

Actuellement, il existe trois façons d'écrire un fichier:

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

    Vous devez attendre le rappel pour vous assurer que le tampon est écrit sur le disque. Ce n'est pas mis en mémoire tampon.

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

    Toutes les données doivent être stockées en même temps; vous ne pouvez pas effectuer d'écritures séquentielles.

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

    Crée un WriteStream, ce qui est pratique car vous n'avez pas besoin d'attendre un rappel. Mais encore une fois, ce n'est pas mis en mémoire tampon.

A WriteStream, comme son nom l'indique, est un flux. Un flux par définition est «un tampon» contenant des données qui se déplacent dans une direction (source ► destination). Mais un flux inscriptible n'est pas nécessairement «tamponné». Un flux est «tamponné» lorsque vous écrivez des nheures, et à un moment donné n+1, le flux envoie le tampon au noyau (car il est plein et doit être vidé).

En d'autres termes: «Un tampon» est l'objet. Qu'il soit «tamponné» ou non est une propriété de cet objet.

Si vous regardez le code, l' WriteStreamhérite d'un Streamobjet accessible en écriture . Si vous faites attention, vous verrez comment ils vident le contenu; ils n'ont pas de système de mise en mémoire tampon.

Si vous écrivez une chaîne, elle est convertie en tampon, puis envoyée à la couche native et écrite sur le disque. Lors de l'écriture de chaînes, ils ne remplissent aucun tampon. Donc, si vous le faites:

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

Tu fais:

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

Cela fait trois appels à la couche d'E / S. Bien que vous utilisiez des «tampons», les données ne sont pas tamponnées. Un flux en mémoire tampon ferait: fs.write(new Buffer ("abc"))un appel à la couche d'E / S.

À partir de maintenant, dans Node.js v0.12 (version stable annoncée le 02/06/2015) prend désormais en charge deux fonctions: cork()et uncork(). Il semble que ces fonctions vous permettront enfin de tamponner / vider les appels d'écriture.

Par exemple, en Java, certaines classes fournissent des flux mis en mémoire tampon ( BufferedOutputStream,BufferedWriter ...). Si vous écrivez trois octets, ces octets seront stockés dans le tampon (mémoire) au lieu d'effectuer un appel d'E / S uniquement pour trois octets. Lorsque le tampon est plein, le contenu est vidé et enregistré sur le disque. Cela améliore les performances.

Je ne découvre rien, je me souviens juste comment un accès au disque doit être fait.

Gabriel Llamas
la source
5
+1 - belle explication. Pour l'écriture de flux, il est important de lire attentivement les documents. Si renvoie faux ou fermant, il est important d'appeler writer.once ('drain', function () {}) ou j'ai raté des lignes qui n'avaient pas été vidées à la fin du processus.
bryanmac
4
Y a-t-il une chance que vous puissiez fournir un exemple d'utilisation cork()et uncork()pour ceux d'entre nous qui veulent essayer le noeud pré-version 0.11?
professormeowingtons
Pour l'instant, Node v0.12 est stable.
août
Selon une analyse du code de GitHub, fs.writeFile semble être la plus populaire des fonctions que vous avez mentionnées. Voici des exemples concrets d'utilisation de fs.writeFile
drorw
Existe-t-il des bibliothèques de qualité de production sur l' npmimplémentation de l'écriture tamponnée?
nponeccop
266

Vous pouvez bien sûr le rendre un peu plus avancé. Non bloquant, écrivant des morceaux et des morceaux, n'écrivant pas le fichier entier à la fois:

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
la source
17
Quelle est la variable 'fd' passée dans le rappel de stream.once?
Scott Tesler
1
@ScottDavidTesler descripteur de fichier afin que vous puissiez fermer le flux après l'avoir terminé.
Alexey Kamenskiy
3
Quand dois-je fermer le flux? Pourquoi est-ce non bloquant? Juste curieux, j'essaie d'écrire dans un fichier journal.
MetaGuru
1
Je ne sais pas si le flux est vidé. Je suppose qu'il est possible de vider le flux à la demande.
Fredrik Andersson
1
@JoLiss Vous devrez l'attendre.
Fredrik Andersson
61

Écriture synchrone

fs.writeFileSync (fichier, données [, options])

fs = require('fs');

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

Écriture asynchrone

fs.writeFile (fichier, données [, options], rappel)

fs = require('fs');

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

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

Lire le système vaut fichier fs (offical) docs .

Moriarty
la source
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');
        })
    });
});
Monsieur P
la source
2
cela montre comment écrire un fichier à l'aide d'opérations fs de niveau inférieur. par exemple, vous pouvez garantir la fin de l'écriture du fichier sur le disque et la publication des descripteurs de fichier.
Sean Glover du
Étant donné que dans cet exemple, le décalage est défini sur «0» (= troisième paramètre de fs.write()), cet exemple ne fonctionne que si tout est suffisamment court pour être écrit en un seul appel d'écriture.
Manfred
31

J'ai aimé Index of ./articles/file-system .

Ça a marché pour moi.

Voir aussi Comment écrire des fichiers dans 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');
});

Contenu de helloworld.txt:

Hello World!

Mise à jour:
Comme dans le nœud Linux, écrivez dans le répertoire actuel, il semble que dans certains autres non, alors j'ajoute ce commentaire juste au cas où: l'
utiliser ROOT_APP_PATH = fs.realpathSync('.'); console.log(ROOT_APP_PATH);pour obtenir où le fichier est écrit.

Sérgio
la source
Où trouver le fichier helloworld.txt? Je ne le trouve dans aucun dossier ... merci.
Kai Feng Chew
dans le dossier que vous exécutez le script
Sérgio
C'est bizarre ... Je ne le trouve nulle part. Sera-t-il caché? merci encore ~
Kai Feng Chew
6
Je viens de le trouver. Utilisation de cette ROOT_APP_PATH = fs.realpathSync ('.'); console.log ( ROOT_APP_PATH ); pour obtenir mon où le fichier écrit. Merci.
Kai Feng Chew
@ Sérgio: faut-il fermer le fichier d'écriture? J'appelle un autre processus et je reçois un message d'erreur concernant le fichier qui est utilisé par un autre processus.
Amir
24

Les réponses fournies sont datées et une nouvelle façon de procéder est:

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

voir les documents ici pour plus d'informations

TrevTheDev
la source
1
(node:23759) ExperimentalWarning: The fs.promises API is experimental
jgraup
@jgraup: utilisez-vous la dernière version de node?
TrevTheDev
Nodev10.15.0
jgraup
7
La fonction de fermeture doit être asynchrone ou cela ne fonctionnera pas.
Zimano
1
@wintercounter C'est assez mignon!
Zimano
20

Je sais que la question posée sur "écrire" mais dans un sens plus général "ajouter" pourrait être utile dans certains cas car il est facile à utiliser en boucle pour ajouter du texte à un fichier (que le fichier existe ou non). Utilisez un "\ n" si vous souhaitez ajouter des lignes, par exemple:

var fs = require('fs');
for (var i=0; i<10; i++){
    fs.appendFileSync("junk.csv", "Line:"+i+"\n");
}
Astra Bear
la source
Puisqu'il est maintenant disponible, je recommande d'utiliser constplutôt que var, c'est const fs = require('fs');-à- dire pour éviter les effets secondaires indésirables, en particulier si vous travaillez avec une base de code un peu plus grande.
Manfred
11

OK, c'est assez simple car Node a une fonctionnalité intégrée pour cela, cela s'appelle fsqui signifie File System et, fondamentalement, NodeJS File System module ...

Vous devez donc d'abord l'exiger dans votre fichier server.js comme ceci:

var fs = require('fs');

fsa peu de méthodes pour écrire dans un fichier, mais ma façon préférée est d'utiliser appendFile, cela ajoutera le contenu au fichier et si le fichier n'existe pas, en créera un, le code pourrait être comme ci-dessous:

fs.appendFile('myFile.txt', 'Hi Ali!', function (err) {
  if (err) throw err;
  console.log('Thanks, It\'s saved to the file!');
});
Alireza
la source
3
les guillemets simples dans la chaîne doivent être échappés.
Tamer
9
 var fs = require('fs');
 fs.writeFile(path + "\\message.txt", "Hello", function(err){
 if (err) throw err;
  console.log("success");
}); 

Par exemple: lire un fichier et écrire dans un autre fichier:

  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
la source
Où vous écrivez les données dans le "to.text" ??
Ravi Shanker Reddy
Qu'est-ce que cette réponse ajoute aux multiples réponses déjà existantes sur writeFile ?
Dan Dascalescu
9

Vous pouvez écrire dans un fichier en utilisant le module fs (système de fichiers).

Voici un exemple de la façon dont vous pouvez le faire:

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');
    }
  });
};

Vous voudrez peut-être également vous débarrasser de cette structure de code de rappel à l'intérieur en utilisant Promises et async/await instructions . Cela rendra la structure du code asynchrone beaucoup plus plate. Pour ce faire, il existe une fonction util.promisify (originale) pratique qui peut être utilisée. Cela nous permet de passer des rappels aux promesses. Jetez un œil à l'exemple avec les fsfonctions ci-dessous:

// 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
la source
1
Pourquoi ces extraits de code et non des morceaux de code? De toute façon, ils ne pourront jamais s'exécuter dans un navigateur.
Zimano
@Zimano Si je comprends bien, la question concernait nodejs, il n'est donc pas nécessaire de pouvoir l'exécuter dans un navigateur.
Manfred
1
@Manfred Exactement! Je pense que vous avez mal compris ce que j'essayais de dire; il ne sert à rien d'avoir des extraits de code car il s'agit de nodejs!
Zimano
5

Ici, nous utilisons w + pour lire / écrire les deux actions et si le chemin du fichier n'est pas trouvé, il sera créé automatiquement.

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');
            })
        });
    }
});

Le contenu signifie ce que vous devez écrire dans le fichier et sa longueur, «content.length».

Gunjan Patel
la source
3

Voici l'exemple de la façon de lire le fichier csv du local et d'écrire le fichier csv au 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
la source
1
Cela introduit toutes sortes de complications (MongoClient, JSON etc.) qui ne se rapportent pas à la question.
Dan Dascalescu
3

fs.createWriteStream(path[,options])

optionspeut également inclure une startoption pour autoriser l'écriture de données à une certaine position après le début du fichier. La modification d'un fichier plutôt que son remplacement peut nécessiter un flagsmode r+plutôt que le mode par défaut w. L'encodage peut être n'importe lequel de ceux acceptés par Buffer .

Si autoCloseest défini sur true (comportement par défaut) sur 'error'ou 'finish'le descripteur de fichier sera fermé automatiquement. SiautoClose est faux, le descripteur de fichier ne sera pas fermé, même en cas d'erreur. Il est de la responsabilité de l'application de la fermer et de s'assurer qu'il n'y a pas de fuite de descripteur de fichier.

Comme ReadStream , si fdest spécifié, WriteStream ignorera l' pathargument et utilisera le descripteur de fichier spécifié. Cela signifie qu'aucun 'open'événement ne sera émis. fddevrait être bloquant; les fds non bloquants doivent être passés à net.Socket .

Si optionsest une chaîne, elle spécifie l'encodage.

Après avoir lu ce long article. Vous devez comprendre comment cela fonctionne. Alors, voici un exemple 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');

la source
createWriteStreama déjà été mentionné dans plusieurs années de réponse avant celui-ci.
Dan Dascalescu
0

Vous pouvez utiliser la bibliothèque easy-file-manager

installer d'abord à partir de npm npm install easy-file-manager

Échantillon pour télécharger et supprimer des fichiers

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
la source
2
This modules is created to save and remove files.. Pas une réponse.
Vert
-1

Vous pouvez écrire dans un fichier par l'exemple de code suivant:

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
la source
1
writeFileavait déjà été donnée plusieurs fois, plusieurs années auparavant. Qu'est-ce que cette réponse ajoute?
Dan Dascalescu
Aussi pourquoi vous ouvrez un fichier? La réponse ne devrait-elle pas concerner l'écriture de fichiers?
Michal