Menulis file di Node.js

1646

Saya sudah mencoba menemukan cara untuk menulis ke file ketika menggunakan Node.js, tetapi tidak berhasil. Bagaimana saya bisa melakukan itu?

Gjorgji
sumber

Jawaban:

2465

Ada banyak detail di API Sistem File . Cara yang paling umum adalah:

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
sumber
26
Saya telah menguji skrip ini menggunakan Node, dan saya mencoba mengubah path file ke "/ home /", tetapi saya mendapatkan kesalahan berikut: { [Error: EACCES, open '/home/test.txt'] errno: 3, code: 'EACCES', path: '/home/test.txt' } Bagaimana saya bisa memodifikasi skrip ini sehingga akan berfungsi di luar /tmp?
Anderson Green
130
Perhatikan juga Anda dapat menggunakan fs.writeFileSync (...) untuk melakukan hal yang sama secara sinkron.
David Erwin
7
Mungkin agak lama, tetapi @AndersonGreen, Anda perlu menjalankan simpul sebagai root atau chmod / home dengan benar untuk mengizinkan izin R / W ke pemilik proses simpul saat ini (nama pengguna Anda sulit) sehingga Anda dapat menulis file
Denys Vitali
39
Sebenarnya, @DenysVitali, masalahnya adalah bahwa jane seharusnya tidak dapat menulis file apa pun /home/.... Secara umum direktori tersebut adalah 755 root: wheel (atau apa pun). Jika simpul ingin menulis file sebagai jane, akan lebih mudah untuk menulis /home/jane/test.txt. Mengubah /homeke sesuatu yang lebih permisif dari 755 adalah kesalahan besar.
jane arc
7
@JaneAvriette Yah, karena dia ingin menyimpan file pada /homedirektori saya sarankan untuk chmod itu. Saya tahu ini bisa menghasilkan masalah keamanan. Tapi yah, jika pengguna ingin menyimpan di sana, itu solusinya. PS: Saya setuju dengan apa yang Saudara katakan (:
Denys Vitali
537

Saat ini ada tiga cara untuk menulis file:

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

    Anda harus menunggu panggilan balik untuk memastikan bahwa buffer ditulis ke disk. Itu tidak buffered.

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

    Semua data harus disimpan pada saat yang sama; Anda tidak dapat melakukan penulisan berurutan.

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

    Membuat WriteStream, yang nyaman karena Anda tidak perlu menunggu panggilan balik. Tetapi sekali lagi, itu tidak buffered.

A WriteStream, seperti namanya, adalah aliran. Streaming menurut definisi adalah “buffer” yang berisi data yang bergerak dalam satu arah (sumber ► tujuan). Tetapi aliran yang dapat ditulisi belum tentu "buffered". Aliran adalah "buffered" ketika Anda menulis nwaktu, dan pada saat itu n+1, aliran mengirimkan buffer ke kernel (karena penuh dan perlu memerah).

Dengan kata lain: "A buffer" adalah objek. Apakah atau tidak "buffered" adalah properti dari objek itu.

Jika Anda melihat kode, WriteStreamwarisan dari Streamobjek yang dapat ditulis . Jika Anda memperhatikan, Anda akan melihat bagaimana mereka menyiram konten; mereka tidak memiliki sistem penyangga.

Jika Anda menulis string, itu dikonversi ke buffer, dan kemudian dikirim ke layer asli dan ditulis ke disk. Saat menulis string, mereka tidak mengisi buffer apa pun. Jadi, jika Anda melakukannya:

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

Kamu lakukan:

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

Itu tiga panggilan ke lapisan I / O. Meskipun Anda menggunakan "buffer", data tidak buffered. Aliran buffered akan melakukan:, fs.write(new Buffer ("abc"))satu panggilan ke lapisan I / O.

Sampai sekarang, di Node.js v0.12 (versi stabil diumumkan 02/06/2015) sekarang mendukung dua fungsi: cork()dan uncork(). Tampaknya fungsi-fungsi ini pada akhirnya akan memungkinkan Anda untuk buffer / flush panggilan tulis.

Sebagai contoh, di Jawa ada beberapa kelas yang menyediakan aliran buffer (BufferedOutputStream , BufferedWriter...). Jika Anda menulis tiga byte, byte ini akan disimpan dalam buffer (memori) alih-alih melakukan panggilan I / O hanya untuk tiga byte. Ketika buffer penuh, konten memerah dan disimpan ke disk. Ini meningkatkan kinerja.

Saya tidak menemukan apa-apa, hanya mengingat bagaimana akses disk harus dilakukan.

Gabriel Llamas
sumber
5
+1 - penjelasan yang bagus. Untuk menulis stream, penting untuk membaca dokumen dengan cermat. Jika mengembalikan false atau closure, penting untuk memanggil writer.once ('drain', function () {}) atau saya melewatkan baris yang tidak terkuras saat proses berakhir.
bryanmac
4
setiap kesempatan Anda bisa memberikan contoh bagaimana menggunakan cork()dan uncork()bagi kita yang ingin mencoba node 0,11 pra-rilis?
professormeowingtons
Sampai sekarang, Node v0.12 stabil.
Agustus
Menurut analisis kode dari GitHub, fs.writeFile tampaknya paling populer dari fungsi yang Anda sebutkan. Berikut adalah contoh dunia nyata untuk menggunakan fs.writeFile
drorw
Apakah ada perpustakaan berkualitas produksi dalam npmmengimplementasikan penulisan buffered?
nponeccop
266

Tentu saja Anda bisa membuatnya sedikit lebih maju. Non-blocking, menulis bit dan potongan, tidak menulis seluruh file sekaligus:

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
sumber
17
Apa variabel 'fd' yang diteruskan ke dalam callback untuk stream.once?
Scott Tesler
1
Deskriptor file @ScottDavidTesler sehingga Anda akan dapat menutup streaming setelah selesai melakukannya.
Alexey Kamenskiy
3
Kapan saya menutup aliran? Mengapa ini tidak menghalangi? Hanya ingin tahu, saya mencoba menulis ke file log.
MetaGuru
1
Saya tidak yakin apakah ketika alirannya memerah. Dugaan saya adalah bahwa ada kemungkinan untuk menyiram aliran sesuai permintaan.
Fredrik Andersson
1
@ JoLiss Anda harus menunggu untuk itu.
Fredrik Andersson
61

Sinkron Tulis

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

fs = require('fs');

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

Asynchronous Write

fs.writeFile (file, data [, opsi], panggilan balik)

fs = require('fs');

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

Dimana

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

Layak dibaca File resmi System (fs) docs .

Moriarty
sumber
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');
        })
    });
});
Tuan P
sumber
2
ini menunjukkan cara menulis file menggunakan operasi fs tingkat rendah. misalnya, Anda dapat menjamin ketika file telah selesai menulis ke disk dan telah merilis deskriptor file.
Sean Glover
Karena dalam contoh ini offset jika diatur ke '0' (= parameter ketiga fs.write()) contoh ini hanya berfungsi jika semuanya cukup pendek untuk ditulis dalam satu panggilan tulis.
Manfred
31

Saya menyukai Indeks ./articles/file-system .

Ini berhasil untuk saya.

Lihat juga Bagaimana cara saya menulis file di 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');
});

Isi dari helloworld.txt:

Hello World!

Pembaruan:
Seperti dalam simpul Linux menulis di direktori saat ini, sepertinya di beberapa orang lain tidak, jadi saya menambahkan komentar ini untuk berjaga-jaga:
Menggunakan ini ROOT_APP_PATH = fs.realpathSync('.'); console.log(ROOT_APP_PATH);untuk mendapatkan tempat file ditulis.

Sérgio
sumber
Di mana menemukan file helloworld.txt? Saya tidak dapat menemukannya di folder apa pun ... terima kasih.
Kai Feng Chew
dalam folder yang Anda jalankan skrip
Sérgio
Aneh ... Saya tidak bisa menemukannya di mana pun. Apakah ini akan disembunyikan? terima kasih lagi ~
Kai Feng Chew
6
Saya baru saja menemukannya. Menggunakan ROOT_APP_PATH = fs.realpathSync ('.') Ini; console.log ( ROOT_APP_PATH ); untuk mendapatkan tempat file saya ditulis. Terima kasih.
Kai Feng Chew
@ Sérgio: apakah kita perlu menutup filefile? Saya memanggil proses lain dan saya menerima pesan kesalahan tentang file yang mulai digunakan oleh beberapa proses lainnya.
Amir
24

Jawaban yang diberikan adalah tanggal dan cara yang lebih baru untuk melakukan ini adalah:

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

lihat dokumen di sini untuk info lebih lanjut

TrevTheDev
sumber
1
(node:23759) ExperimentalWarning: The fs.promises API is experimental
jgraup
@ jgraup: apakah Anda menggunakan versi terbaru dari simpul?
TrevTheDev
Nodev10.15.0
jgraup
7
Fungsi penutup harus async atau ini tidak akan berfungsi.
Zimano
1
@wintercounter Sangat manis!
Zimano
19

Saya tahu pertanyaan yang diajukan tentang "tulis" tetapi dalam arti yang lebih umum "tambahkan" mungkin berguna dalam beberapa kasus karena mudah digunakan dalam satu lingkaran untuk menambahkan teks ke file (apakah file ada atau tidak). Gunakan "\ n" jika Anda ingin menambahkan baris misalnya:

var fs = require('fs');
for (var i=0; i<10; i++){
    fs.appendFileSync("junk.csv", "Line:"+i+"\n");
}
Beruang Astra
sumber
Karena itu sekarang tersedia saya akan recommmend menggunakan constbukan var, yaituconst fs = require('fs'); , untuk menghindari efek samping yang tidak diinginkan, khususnya jika Anda bekerja dengan basis kode yang agak lebih besar.
Manfred
11

OK, ini cukup sederhana karena Node memiliki fungsi bawaan untuk ini, ini disebut fskependekan dari File System dan pada dasarnya, modul NodeJS File System ...

Jadi pertama-tama memerlukannya di file server.js Anda seperti ini:

var fs = require('fs');

fsmemiliki beberapa metode untuk menulis ke file, tetapi cara pilihan saya adalah menggunakan appendFile, ini akan menambahkan barang ke file dan jika file tidak ada, akan membuat satu, kode bisa seperti di bawah ini:

fs.appendFile('myFile.txt', 'Hi Ali!', function (err) {
  if (err) throw err;
  console.log('Thanks, It\'s saved to the file!');
});
Alireza
sumber
3
Kutipan tunggal dalam string harus diloloskan.
Tamer
9
 var fs = require('fs');
 fs.writeFile(path + "\\message.txt", "Hello", function(err){
 if (err) throw err;
  console.log("success");
}); 

Misalnya: membaca file dan menulis ke file lain:

  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
sumber
Di mana Anda memasukkan data ke dalam "to.text" ??
Ravi Shanker Reddy
Apa yang ditambahkan jawaban ini ke beberapa jawaban yang sudah ada writeFile?
Dan Dascalescu
9

Anda dapat menulis ke file menggunakan fs modul (sistem file).

Berikut adalah contoh bagaimana Anda dapat melakukannya:

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

Anda mungkin juga ingin menyingkirkan struktur kode callback-inside-callback ini dengan menggunakan Janji dan async/ awaitpernyataan. Ini akan membuat struktur kode asinkron lebih rata. Untuk melakukan itu ada fungsi util.promisify (asli) yang praktis dapat digunakan. Hal ini memungkinkan kita untuk beralih dari panggilan balik ke janji. Lihatlah contoh dengan fsfungsi di bawah ini:

// 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
sumber
1
Mengapa potongan ini dan bukan potongan kode? Mereka tidak akan pernah bisa berjalan di browser.
Zimano
@ Zimano Seperti yang saya pahami, pertanyaannya adalah tentang nodejs jadi tidak perlu bisa berjalan di browser.
Manfred
1
@Manfred Persis! Saya pikir Anda salah mengerti apa yang ingin saya katakan; tidak ada gunanya memiliki snippet karena itu nodejs!
Zimano
5

Di sini kita menggunakan w + untuk membaca / menulis kedua tindakan dan jika path file tidak ditemukan maka akan dibuat secara otomatis.

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

Konten berarti apa yang Anda harus tulis ke file dan panjangnya, 'content.length'.

Gunjan Patel
sumber
3

Berikut adalah contoh cara membaca file csv dari lokal dan menulis file csv ke lokal.

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
sumber
1
Ini memperkenalkan semua jenis komplikasi (MongoClient, JSON dll.) Yang tidak berkaitan dengan pertanyaan.
Dan Dascalescu
3

fs.createWriteStream(path[,options])

optionsmungkin juga menyertakan startopsi untuk memungkinkan penulisan data pada beberapa posisi melewati awal file. Memodifikasi file daripada menggantinya mungkin memerlukan flagsmode r+daripada mode default w. Pengkodean dapat berupa salah satu dari yang diterima oleh Buffer .

Jika autoClosedisetel ke true (perilaku default) pada 'error'atau 'finish'deskriptor file akan ditutup secara otomatis. JikaautoClose salah, maka deskriptor file tidak akan ditutup, bahkan jika ada kesalahan. Adalah tanggung jawab aplikasi untuk menutupnya dan memastikan tidak ada kebocoran deskriptor file.

Seperti ReadStream , jika fdditentukan, WriteStream akan mengabaikan pathargumen dan akan menggunakan deskriptor file yang ditentukan. Ini berarti bahwa tidak ada 'open'acara yang akan dipancarkan. fdharus memblokir; non-blocking fdharus diteruskan ke net.Socket .

Jika optionsstring, maka itu menentukan pengkodean.

Setelah itu, baca artikel panjang ini. Anda harus mengerti cara kerjanya. Jadi, inilah contohnya 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');

sumber
createWriteStreamsudah disebutkan dalam beberapa jawaban beberapa tahun sebelumnya .
Dan Dascalescu
0

Anda bisa menggunakan perpustakaan easy-file-manager

instal dulu dari npm npm install easy-file-manager

Contoh untuk mengunggah dan menghapus file

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
sumber
2
This modules is created to save and remove files.. Bukan jawaban.
Hijau
-1

Anda dapat menulis dalam file dengan contoh kode berikut:

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
sumber
1
writeFilesudah diberikan sebagai jawaban beberapa kali, bertahun-tahun yang lalu. Apa yang ditambahkan jawaban ini?
Dan Dascalescu
Juga mengapa Anda membuka file? Bukankah seharusnya jawabannya tentang menulis file?
Michal