Fs.readFile sitesinden veri alma


297
var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
});
console.log(content);

Günlükler undefined, neden?


1
fs.readFileSync ayrıca unicode utf8 biçiminde olsa bile bir dosyayı okumak için harika özelliklere sahiptir.
Praneeth

NB fs.readFile bunu da yapabilir ^ aşağıdaki cevabımı gör
Dominic

Yanıtlar:


348

@Raynos'un söylediklerini ayrıntılı olarak açıklamak için, tanımladığınız işlev eşzamansız bir geri aramadır. Hemen yürütülmez, dosya yükleme tamamlandığında yürütülür. ReadFile öğesini çağırdığınızda, denetim hemen döndürülür ve sonraki kod satırı yürütülür. Dolayısıyla console.log'u çağırdığınızda, geri aramanız henüz çağrılmadı ve bu içerik henüz ayarlanmadı. Eşzamansız programlamaya hoş geldiniz.

Örnek yaklaşımlar

const fs = require('fs');
// First I want to read the file
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    const content = data;

    // Invoke the next step here however you like
    console.log(content);   // Put all of the code here (not the best solution)
    processFile(content);   // Or put the next step in a function and invoke it
});

function processFile(content) {
    console.log(content);
}

Ya da daha iyisi, Raynos örneğinin gösterdiği gibi, çağrınızı bir işleve sarın ve kendi geri aramalarınızı iletin. (Görünüşe göre bu daha iyi bir uygulamadır) Async çağrılarınızı geri arama yapan bir işlevle sarma alışkanlığına girmenin size çok fazla sorun ve dağınık kod kazandıracağını düşünüyorum.

function doSomething (callback) {
    // any async callback invokes callback with response
}

doSomething (function doSomethingAfter(err, result) {
    // process the async result
});

2
Sync I / O'nun yeri var - küçük bir yapı sistemi veya aracı yapıyorsanız sorun yok. Daha büyük sistemlerde veya sunucu uygulamalarında en iyi uygulama bundan kaçınmaktır.
Rob

28
Her şey bir web sunucusu değildir. Ve sunucu istek almaya başlamadan önce tek seferlik çağrılar için yöntemlerin senkronizasyon sürümlerini kullanma konusunda korkunç bir şey yoktur. Düğüm kullanan herkes, kullanmadan önce nedenini gerçekten anlamalıdır. Kesinlikle bu konuda rant-bloglama önce.
Erik Reppen


7
'utf8'Dosya adından sonra ek bir parametre olarak eklemeniz gerekir , aksi takdirde sadece bir tampon döndürür. Bakınız: stackoverflow.com/questions/9168737/…
DollarAkshay

252

Bunun için aslında bir Eşzamanlı işlev vardır:

http://nodejs.org/api/fs.html#fs_fs_readfilesync_filename_encoding

eşzamanlı olmayan

fs.readFile(filename, [encoding], [callback])

Bir dosyanın tüm içeriğini eşzamansız olarak okur. Misal:

fs.readFile('/etc/passwd', function (err, data) {
  if (err) throw err;
  console.log(data);
});

Geri arama, verilerin dosyanın içeriği olduğu iki bağımsız değişkenden (err, veri) geçirilir.

Kodlama belirtilmezse, ham arabellek döndürülür.


SENKRON

fs.readFileSync(filename, [encoding])

Fs.readFile dosyasının eşzamanlı sürümü. Dosyaadı adlı dosyanın içeriğini döndürür.

Kodlama belirtilirse, bu işlev bir dize döndürür. Aksi takdirde bir tampon döndürür.

var text = fs.readFileSync('test.md','utf8')
console.log (text)

Hızlı soru, readFile eşzamanlı sürümünde döndürülen arabellek kullanımı nedir? Bir dosyayı eşzamanlı olarak okursam ve herhangi bir kodlamayı geçmezse, tampon yazdırır, bunu nasıl kullanabilirim? Teşekkür ederim.
codingbbq

12
Son zamanlarda bu konuda deneyimim vardı. Diyelim ki tamponumuz data. if (Buffer.isBuffer( data){ result = data.toString('utf8'); }Şimdi arabelleği okunabilir metne dönüştürdük. Bu, bir düz metin dosyasını okumak veya dosyayı biçim türlerine karşı test etmek için iyidir. Örneğin bir JSON dosyası olup olmadığını görmek için bir deneyin / yakalamak yapabilir; ancak arabellek metne dönüştürüldükten sonra. Daha fazla bilgi için buraya bakın: nodejs.org/api/buffer.html
Logan

Ayrıca bildiğim kadarıyla tamponlar sekizli akışlardır ve "parça parça" veri göndermek için iyidir. Tamponun benzer bir şey olduğunu görmüş olmalısınız AF 42 F1. İstemci-sunucu-istemci iletişimi için çok pratik.
Logan

113
function readContent(callback) {
    fs.readFile("./Index.html", function (err, content) {
        if (err) return callback(err)
        callback(null, content)
    })
}

readContent(function (err, content) {
    console.log(content)
})

6
Çok teşekkürler, 15
puanım

Merhaba, kodunun ilk satırında, function readContent(callback)vardır callbackayrılmış bir kelime? Yani, bu, özel işlevleriniz için geri çağrıları uygulamanın standart yolu mu? Düğüm öğrenmeye yeni başladım.
Amal Antony

3
Merhaba Amal. Geri arama basitçe işlevine iletilen argüman, olabilir eventya cda istediğiniz herhangi bir isim olabilir - Javascript'te ayrılmış bir kelime değildir ve aynı şeyin Node.js'ye uzandığını varsayarım.
RealDeal_EE'18

readContent(function (err, content)işlevi parametre olarak kullanırken bana bir sözdizimi hatası veriyor.
monsto

66

ES7 ile Vaatleri Kullanma

Mz / fs ile eşzamansız kullanım

mzModül merkez düğüm kütüphanesinin promisified sürümlerini içerir. Bunları kullanmak basittir. Önce kütüphaneyi kurun ...

npm install mz

Sonra...

const fs = require('mz/fs');
fs.readFile('./Index.html').then(contents => console.log(contents))
  .catch(err => console.error(err));

Alternatif olarak, bunları eşzamansız işlevlerde yazabilirsiniz:

async function myReadfile () {
  try {
    const file = await fs.readFile('./Index.html');
  }
  catch (err) { console.error( err ) }
};

6
bu gelecek ve herkes tarafından çok beğenilmeli :) teşekkürler
PirateApp

2
ilgi çekici görünüyor. Bir yazım hatası: 'console.error (catch)', 'console.error (err)' olması gerektiğini düşünüyorum).
philwalk

2
Fazladan bir paket eklemek istemiyorsanız, aşağıdaki
@doctorlee'nin

18
var data = fs.readFileSync('tmp/reltioconfig.json','utf8');

bu dosyayı bir çıktıyı tampon olarak kodlamadan senkronize olarak çağırmak için kullanın.


2
Güzel baskının
başlayabilmesi

brifing ve en iyisi!
Elmas

13

Bu hat çalışacak,

const content = fs.readFileSync('./Index.html', 'utf8');
console.log(content);

1
7 yıl geçti :) fs.readFileSyncsenkronizasyon yöntemidir, bu yüzden awaitorada gerek yok. Await , senkronizasyon koduna benzer sözdizimi ile zaman uyumsuz kod yazmak istediğinizde vaatlerde ( nodejs.org/api/fs.html#fs_fs_promises_api ) faydalıdır .
karaxuna

@karaxuna, evet. çıkarıldı. Bugün bu davaya geldim ve yukarıdaki kodu kullanarak çözdüm.
Aravin

1
Bu en basit cevap. Zaman uyumsuzluğa ihtiyacınız yoksa, neden dünyada hiç zaman uyumsuz sürümle, geri aramalar, zaman uyumsuzluk / beklemeyle vb. Bu yol.
Ördeklerin Efendisi

8
const fs = require('fs')
function readDemo1(file1) {
    return new Promise(function (resolve, reject) {
        fs.readFile(file1, 'utf8', function (err, dataDemo1) {
            if (err)
                reject(err);
            else
                resolve(dataDemo1);
        });
    });
}
async function copyFile() {

    try {
        let dataDemo1 = await readDemo1('url')
        dataDemo1 += '\n' +  await readDemo1('url')

        await writeDemo2(dataDemo1)
        console.log(dataDemo1)
    } catch (error) {
        console.error(error);
    }
}
copyFile();

function writeDemo2(dataDemo1) {
    return new Promise(function(resolve, reject) {
      fs.writeFile('text.txt', dataDemo1, 'utf8', function(err) {
        if (err)
          reject(err);
        else
          resolve("Promise Success!");
      });
    });
  }

5
Lütfen sadece cevabınıza kod koymayın ... neden farklı olduğunu ve sorunu nasıl çözdüğünü açıklayın.
Studocwho

@doctorlee Bu aslında benim için çalışıyor, herhangi bir harici kütüphane olmadan. Açıklama mutlaka gereklidir.
Ashutosh Chamoli

7

eşitleme ve zaman uyumsuz dosya okuma yolu:

//fs module to read file in sync and async way

var fs = require('fs'),
    filePath = './sample_files/sample_css.css';

// this for async way
/*fs.readFile(filePath, 'utf8', function (err, data) {
    if (err) throw err;
    console.log(data);
});*/

//this is sync way
var css = fs.readFileSync(filePath, 'utf8');
console.log(css);

Düğüm Hilesi read_file adresinde mevcut .


7

Söylendiği gibi, fs.readFile asenkron bir eylemdir. Bu, düğüme bir dosyayı okumasını söylediğinizde, bunun biraz zaman alacağını ve bu arada düğümün aşağıdaki kodu çalıştırmaya devam ettiğini düşünmeniz gerektiği anlamına gelir. Senin durumunda bu kadar: console.log(content);.

Kodunuzun bir kısmını uzun bir yolculuk için göndermek gibi (büyük bir dosyayı okumak gibi).

Yazdığım yorumlara bir göz atın:

var content;

// node, go fetch this file. when you come back, please run this "read" callback function
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
});

// in the meantime, please continue and run this console.log
console.log(content);

Bu yüzden content oturum açtığınızda hala boş. düğüm henüz dosyanın içeriğini almadı.

Bu console.log(content), hemen sonra geri arama işlevinin içinde hareket ederek çözülebilir content = data;. Bu şekilde, düğüm dosyayı okuduktan ve sonra contentbir değer aldığında günlüğü görürsünüz .


6

Bu eski geri arama işlevlerini daha zarif hale getirmek için yerleşik promisify kitaplığını (Node 8+) kullanın.

const fs = require('fs');
const util = require('util');

const readFile = util.promisify(fs.readFile);

async function doStuff() {
  try {
    const content = await readFile(filePath, 'utf8');
    console.log(content);
  } catch (e) {
    console.error(e);
  }
}

Tek satırda olabilir const doStuff = async (filePath) => fs.readFileSync(filePath, 'utf8');, util.promisify wrap gerek yok.
rab

1
Senkronizasyon sürümünü kullanmamak bunun noktasıdır ve onu çağırırken hataları ele almalısınız
Dominic

4
var fs = require('fs');
var path = (process.cwd()+"\\text.txt");

fs.readFile(path , function(err,data)
{
    if(err)
        console.log(err)
    else
        console.log(data.toString());
});

2
var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
});
console.log(content);

Bunun nedeni, düğümün eşzamansız olması ve okuma işlevini beklememesi ve program başlar başlamaz değeri tanımsız olarak konsolide etmesidir. İşlemek için vaatler, jeneratörler vb. Kullanabiliriz. Sözü bu şekilde kullanabiliriz.

new Promise((resolve,reject)=>{
    fs.readFile('./index.html','utf-8',(err, data)=>{
        if (err) {
            reject(err); // in the case of error, control flow goes to the catch block with the error occured.
        }
        else{
            resolve(data);  // in the case of success, control flow goes to the then block with the content of the file.
        }
    });
})
.then((data)=>{
    console.log(data); // use your content of the file here (in this then).    
})
.catch((err)=>{
    throw err; //  handle error here.
})

1

dosyayı okuyabilirsin

var readMyFile = function(path, cb) {
      fs.readFile(path, 'utf8', function(err, content) {
        if (err) return cb(err, null);
        cb(null, content);
      });
    };

Ekleyerek dosyaya yazabilirsiniz,

var createMyFile = (path, data, cb) => {
  fs.writeFile(path, data, function(err) {
    if (err) return console.error(err);
    cb();
  });
};

ve hatta birlikte zincirleme

var readFileAndConvertToSentence = function(path, callback) {
  readMyFile(path, function(err, content) {
    if (err) {
      callback(err, null);
    } else {
      var sentence = content.split('\n').join(' ');
      callback(null, sentence);
    }
  });
};

1

Kabaca söylemek gerekirse, doğası gereği asenkron olan node.js ile uğraşıyorsunuz.

Zaman uyumsuzluk hakkında konuştuğumuzda, başka bir şeyle uğraşırken bilgi veya veri yapmaktan veya işlemekten bahsediyoruz. Paralel ile eşanlamlı değildir, lütfen hatırlatırız.

Senin kodun:

var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
});
console.log(content);

Örneğin, temel olarak önce console.log bölümünü yapar, böylece 'içerik' değişkeni tanımsız olur.

Çıktıyı gerçekten istiyorsanız, bunun gibi bir şey yapın:

var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
    console.log(content);
});

Bu eşzamansız. Alışmak zor olacak, ama olan bu. Yine, bu zaman uyumsuzluğun ne olduğunun kaba ama hızlı bir açıklamasıdır.


1

Aşağıdaki fonksiyon asyncsarma veya söz thenzincirleri için işe yarar

const readFileAsync =  async (path) => fs.readFileSync(path, 'utf8');
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.