Node.js'de dosya yazma


1646

Node.js kullanırken bir dosyaya yazmak için bir yol bulmaya çalışıyorum, ancak başarılı olamadı. Bunu nasıl yapabilirim?

Yanıtlar:


2464

Dosya Sistemi API'sında çok fazla ayrıntı var . En yaygın yol:

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

26
Düğümü kullanarak bu komut dosyasını sınadım ve "/ home /" için dosya yolunu değiştirmeyi denedim, ancak aşağıdaki hatayı aldım: { [Error: EACCES, open '/home/test.txt'] errno: 3, code: 'EACCES', path: '/home/test.txt' } Bu komut dosyasını, dışında çalışacak şekilde nasıl değiştirebilirim /tmp?
Anderson Green

130
Aynı şeyi eşzamanlı olarak gerçekleştirmek için fs.writeFileSync (...) kullanabileceğinizi de unutmayın.
David Erwin

7
Belki biraz eski, ama @AndersonGreen, mevcut düğüm işlemi sahibine (kullanıcı adınız zor) R / W izinlerine izin vermek için düğümü kök veya chmod / home olarak çalıştırmanız gerekiyor - böylece dosyayı yazabilirsiniz
Denys Vitali

39
Aslında, @DenysVitali, sorun jane içine herhangi bir dosya yazmak mümkün olmamasıdır /home/.... Genellikle bu dizin 755 root: wheel (ya da her neyse). Düğüm bir dosyayı jane olarak yazmak istiyorsa, yazmak daha kolay olacaktır /home/jane/test.txt. 755'ten /homedaha hoşgörülü bir şeye geçmek çok büyük bir hatadır.
jane arc

7
@JaneAvriette Dosyayı /homedizine kaydetmek istediği için chmod önerdim . Bir güvenlik sorunu yaratabileceğini biliyorum. Ancak, kullanıcı oraya kaydetmek istiyorsa, çözüm budur. Not: Söylediklerinize katılıyorum (:
Denys Vitali

537

Şu anda bir dosya yazmanın üç yolu vardır:

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

    Arabelleğin diske yazıldığından emin olmak için geri aramayı beklemeniz gerekir. Arabelleğe alınmadı.

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

    Tüm veriler aynı anda saklanmalıdır; sıralı yazma işlemleri gerçekleştiremezsiniz.

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

    Uygun bir a oluşturur WriteStream, çünkü geri arama için beklemenize gerek yoktur. Ama yine, tamponlu değil.

A WriteStream, adından da anlaşılacağı gibi, bir akıştır. Tanıma göre bir akış, bir yönde hareket eden verileri içeren bir kaynaktır (kaynak ► hedef). Ancak yazılabilir bir akış mutlaka “arabelleğe alınmaz”. Bir akış zaman yazdığınızda “arabelleğe alınır” nve zamanla n+1akış arabelleği çekirdeğe gönderir (çünkü dolu ve yıkanması gerekir).

Başka bir deyişle: “Tampon” nesnedir. “Arabelleğe alınıp alınmadığı” o nesnenin bir özelliğidir.

WriteStreamKoda bakarsanız, yazılabilir bir Streamnesneden miras alır . Dikkat ederseniz, içeriği nasıl temizlediklerini göreceksiniz; herhangi bir tamponlama sistemi yoktur.

Bir dize yazarsanız, bir ara belleğe dönüştürülür ve sonra yerel katmana gönderilir ve diske yazılır. Dizeleri yazarken herhangi bir arabellek doldurmuyorlar. Yani, eğer yaparsanız:

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

Yapıyoruz:

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

Bu , G / Ç katmanına yapılan üç çağrıdır. “Arabellekler” kullanmanıza rağmen veriler arabelleğe alınmaz. Arabelleklenmiş bir akış şunları yapar: fs.write(new Buffer ("abc"))G / Ç katmanına bir çağrı.

Şu an itibariyle, Node.js v0.12'de (kararlı sürüm 02/06/2015 duyuruldu) şimdi iki işlevi desteklemektedir: cork()ve uncork(). Bu işlevler sonunda yazma çağrılarını arabelleğe almanıza / temizlemenize izin verecek gibi görünüyor.

Örneğin, Java'da arabellekli akışlar ( BufferedOutputStream, BufferedWriter...) sağlayan bazı sınıflar vardır . Üç bayt yazarsanız, bu baytlar yalnızca üç baytlık bir G / Ç çağrısı yapmak yerine tamponda (bellekte) saklanır. Arabellek dolduğunda içerik temizlenir ve diske kaydedilir. Bu performansı artırır.

Hiçbir şey keşfetmiyorum, sadece disk erişiminin nasıl yapılması gerektiğini hatırlıyorum.


5
+1 - güzel açıklama. Yazma akışı için belgeleri dikkatlice okumak önemlidir. Yanlış veya kapanış döndürürse, writer.once ('drain', function () {}) öğesini çağırmak önemlidir veya işlem sona erdiğinde boşaltılamayan hatları kaçırdım.
bryanmac

4
herhangi bir şansın nasıl kullanılacağına cork()ve uncork()ön sürüm 0.11 düğümünü denemek isteyenlere bir örnek verebilir misiniz ?
professormeowingtons

Şu an itibariyle, v0.12 Düğümü kararlıdır.
ağustos

GitHub'ın kod analizine göre, fs.writeFile, bahsettiğiniz işlevlerin en popüler gibi görünüyor. İşte fs.writeFile'ı kullanmak için gerçek dünya örnekleri
drorw

npmArabellek yazımı uygulama konusunda üretim kalitesi kütüphaneleri var mı?
nponeccop

266

Elbette biraz daha gelişmiş yapabilirsiniz. Bloke olmayan, bit ve parça yazma, tüm dosyayı bir kerede yazmamak:

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

17
Stream.once için geri aramaya iletilen 'fd' değişkeni nedir?
Scott Tesler

1
@ScottDavidTesler dosya tanımlayıcı, böylece işlemi tamamladıktan sonra akışı kapatabilirsiniz.
Alexey Kamenskiy

3
Akışı ne zaman kapatacağım? Bu neden engellemiyor? Sadece merak ediyorum, bir günlük dosyasına yazmaya çalışıyorum.
MetaGuru

1
Akışın ne zaman yıkanacağından emin değilim. Benim tahminim, akışı istek üzerine yıkamak için bir olasılık var.
Fredrik Andersson

1
@JoLiss Beklemek zorunda kalacaksınız.
Fredrik Andersson

61

Senkron Yazma

fs.writeFileSync (dosya; veri [, seçenekler])

fs = require('fs');

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

Asenkron Yazma

fs.writeFile (dosya; veri [, seçenekler], geri arama)

fs = require('fs');

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

Nerede

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

Resmi Dosya Sistemi (fs) belgelerini okumaya değer .


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

2
bu, alt düzey fs işlemlerini kullanarak bir dosyanın nasıl yazılacağını gösterir. örneğin, dosyanın diske yazmayı bitirdiğini ve dosya tanımlayıcılarını yayınladığını garanti edebilirsiniz.
Sean Glover

Bu örnekte, '0' (= üçüncü parametresi fs.write()) olarak ayarlandığında ofset bu örnek yalnızca her şeyin tek bir yazma çağrısında yazılacak kadar kısa olması durumunda çalışır.
Manfred

31

Ben sevdim ./articles/file-system ait Index .

Benim için çalıştı.

Ayrıca bkz . Node.js dosyasına nasıl dosya yazarım? .

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

Helloworld.txt içeriği:

Hello World!

Güncelleme:
Linux düğümünde olduğu gibi, mevcut dizinde yazıyor, bazılarında yok gibi görünüyor, bu yüzden şu durumda bu yorumu ekliyorum: Dosyanın yazıldığı yeri almak için
bunu kullanma ROOT_APP_PATH = fs.realpathSync('.'); console.log(ROOT_APP_PATH);.


Helloworld.txt dosyası nerede bulunur? Herhangi bir klasörde bulamıyorum ... teşekkürler.
Kai Feng Çiğnemek

komut dosyasını çalıştırdığınız klasörde
Sérgio

Bu garip ... Hiçbir yerde bulamıyorum. Gizli olacak mı? tekrar teşekkürler ~
Kai Feng Chew

6
Az önce buldum. Bu ROOT_APP_PATH = fs.realpathSync ('.'); console.log ( ROOT_APP_PATH ); dosyanın nerede yazıldığını görmek için. Teşekkürler.
Kai Feng Çiğnemek

@ Sérgio: yazma dosyasını kapatmamız gerekiyor mu? Başka bir işlem çağırıyorum ve dosya ile ilgili bir hata mesajı alıyorum başka bir işlem tarafından kullanılmaya başlanır.
Amir

24

Verilen cevaplar tarihli ve bunu yapmanın daha yeni bir yolu:

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

daha fazla bilgi için buradaki belgelere bakın


1
(node:23759) ExperimentalWarning: The fs.promises API is experimental
19:19

@jgraup: Düğümün en son sürümünü mü kullanıyorsunuz?
TrevTheDev

Düğümv10.15.0
jgraup

7
Muhafaza işlevi zaman uyumsuz olmalıdır, aksi takdirde çalışmaz.
Zimano

1
@wintercounter Bu çok tatlı!
Zimano

19

Ben "yazma" hakkında sorulan soru biliyorum ama daha genel anlamda "append" bir dosyaya metin eklemek için bir döngüde (dosya var olup olmadığını) kullanımı kolay olduğu için bazı durumlarda yararlı olabilir. Satır eklemek istiyorsanız "\ n" kullanın, örneğin:

var fs = require('fs');
for (var i=0; i<10; i++){
    fs.appendFileSync("junk.csv", "Line:"+i+"\n");
}

Artık var yana kullanıyorum recommmend ediyorum constyerine var, yani const fs = require('fs');sen biraz daha büyük kod tabanı ile çalışıyorsanız özellikle istenmeyen yan etkilerini önlemek için.
Manfred

11

Tamam, denir, Düğüm yerleşik olarak işlevsellik bunun için oldukça basit fsaçılımı Dosya Sistemi ve temelde, NodeJS Dosya Sistemi modülü ...

Bu yüzden önce server.js dosyanızda şu şekilde olmasını isteyin :

var fs = require('fs');

fsdosyaya yazmak için birkaç yöntem var, ancak benim tercih ettiğim yol kullanmak appendFile, bu dosyayı dosyaya ekler ve dosya yoksa, bir tane oluşturur, kod aşağıdaki gibi olabilir:

fs.appendFile('myFile.txt', 'Hi Ali!', function (err) {
  if (err) throw err;
  console.log('Thanks, It\'s saved to the file!');
});

3
dizedeki tek tırnaktan kaçılmalıdır.
Tamer

9
 var fs = require('fs');
 fs.writeFile(path + "\\message.txt", "Hello", function(err){
 if (err) throw err;
  console.log("success");
}); 

Örneğin: dosyayı oku ve başka bir dosyaya yaz:

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

Nerede "to.text" içine veri yazma ??
Ravi Shanker Reddy

Bu cevap halihazırda var olan birden fazla cevaba ne katıyor writeFile?
Dan Dascalescu

9

Bir dosyaya fs (dosya sistemi) modülünü kullanarak yazabilirsiniz .

İşte bunu nasıl yapabileceğinize bir örnek:

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

Promises ve async/ awaitifadeleri kullanarak bu geri arama içi geri arama kodu yapısından kurtulmak isteyebilirsiniz . Bu, eşzamansız kod yapısını çok daha düz hale getirecektir. Bunu yapmak için kullanışlı bir util.promisify (orijinal) işlevi kullanılabilir. Bu, geri aramalardan vaatlere geçmemizi sağlar. fsAşağıdaki işlevlere sahip örneğe bir göz atı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);
}

1
Bu parçacıklar neden kod parçaları değil, neden? Zaten hiçbir zaman bir tarayıcıda çalışamazlar.
Zimano

@Zimano Anladığım kadarıyla soru nodejs'le ilgiliydi, bu yüzden bir tarayıcıda çalışmasına gerek yok.
Manfred

1
@Manfred Aynen! Sanırım ne demeye çalıştığımı yanlış anladın; nodejs olduğundan snippet'lere sahip olmanın bir anlamı yok!
Zimano

5

Burada her iki eylemi okumak / yazmak için w + kullanırız ve dosya yolu bulunmazsa otomatik olarak oluşturulur.

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

İçerik, dosyaya yazmanız gereken şey ve uzunluğu olan 'content.length' anlamına gelir.


3

Yerelden csv dosyasının nasıl okunacağına ve csv dosyasının yerel olarak nasıl yazıldığına dair bir örnek.

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
Bu, soru ile ilgili olmayan her türlü komplikasyonu (MongoClient, JSON vb.) Sunar.
Dan Dascalescu

3

fs.createWriteStream(path[,options])

optionsayrıca start, dosyanın başlangıcından sonraki bir konumdaki verilerin yazılmasına izin verme seçeneği de içerebilir . Bir dosyayı değiştirmek yerine değiştirmek , varsayılan mod yerine bir flagsmod gerektirebilir . Kodlama Tampon tarafından kabul edilenlerden herhangi biri olabilir .r+w

Eğer autoClosetrue (varsayılan davranış) olarak ayarlandığında 'error'veya 'finish'dosya tanıtıcı otomatik olarak kapatılır. EğerautoClose yanlış, o zaman dosya tanıtıcı bir hata olsa bile, kapalı olmayacak. Kapatmak ve hiçbir dosya tanımlayıcı sızıntısı olmadığından emin olmak uygulamanın sorumluluğundadır.

Gibi ReadStream eğer fdbelirtilmişse, WriteStream yok sayacaktır pathargüman ve belirtilen dosya tanıtıcı kullanacaktır. Bu, hiçbir 'open'olay yayınlamayacağı anlamına gelir . fdengelleme olmalı; tıkanmasız ağafd geçirilmelidir .

Eğer options bir dizedir, o zaman kodlanmasını gerektirir.

Sonra bu uzun makaleyi okudum. Nasıl çalıştığını anlamalısınız. İşte size bir örnek 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');

createWriteStreamZaten sözü edilen çoklu cevap yıllar önce bu bir.
Dan Dascalescu

0

Kütüphaneyi kullanabilirsiniz easy-file-manager

önce npm'den yükle npm install easy-file-manager

Dosya yüklemek ve kaldırmak için örnek

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

2
This modules is created to save and remove files.. Cevap değil.
Yeşil

-1

Aşağıdaki kod örneğiyle bir dosyaya yazabilirsiniz:

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

1
writeFileyıllar önce birçok kez cevap olarak verilmişti. Bu cevap ne ekliyor?
Dan Dascalescu

Ayrıca neden od açın? Cevap dosya yazmakla ilgili değil mi?
Michal
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.