Получить данные из fs.readFile

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

бревна undefined, Зачем?

17 ответов

Решение

Чтобы пояснить, что сказал @Raynos, определенная вами функция является асинхронным обратным вызовом. Он не выполняется сразу, а выполняется после завершения загрузки файла. Когда вы вызываете readFile, управление возвращается немедленно и выполняется следующая строка кода. Поэтому, когда вы вызываете console.log, ваш обратный вызов еще не был вызван, и этот контент еще не был установлен. Добро пожаловать в асинхронное программирование.

Пример подходов

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

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

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

Или, что еще лучше, как показывает пример Raynos, оберните ваш вызов в функцию и передайте свои собственные обратные вызовы. (Очевидно, это лучшая практика). Я думаю, что привычка заключать в асинхронные вызовы функцию, которая принимает обратный вызов, избавит вас от большого количества хлопот и грязного кода.

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

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

На самом деле есть синхронная функция для этого:

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

Асинхронный

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

Асинхронно читает все содержимое файла. Пример:

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

Обратному вызову передаются два аргумента (err, data), где data - это содержимое файла.

Если кодировка не указана, возвращается необработанный буфер.


Синхронная

fs.readFileSync(filename, [encoding])

Синхронная версия fs.readFile. Возвращает содержимое файла с именем filename.

Если указано кодирование, то эта функция возвращает строку. В противном случае он возвращает буфер.

var text = fs.readFileSync('test.md','utf8')
console.log (text)
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)
})

Использование обещаний с ES7

Асинхронное использование с mz/fs

mz Модуль предоставляет обещанные версии библиотеки базового узла. Использовать их просто. Сначала установите библиотеку...

npm install mz

Затем...

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

В качестве альтернативы вы можете написать их в асинхронных функциях:

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

Эта линия будет работать,

const content = fs.readFileSync('./Index.html', 'utf8');
console.log(content);
var data = fs.readFileSync('tmp/reltioconfig.json','utf8');

используйте это для синхронного вызова файла, без кодирования его выводимых данных в виде буфера.

Используйте встроенную библиотеку Promisify, чтобы сделать эти старые функции обратного вызова более элегантными.

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

Как сказано, fs.readFile это асинхронное действие. Это означает, что когда вы указываете узлу читать файл, вам нужно учитывать, что это займет некоторое время, а тем временем узел продолжал выполнять следующий код. В вашем случае это: console.log(content);,

Это похоже на отправку какой-то части вашего кода в долгое путешествие (например, чтение большого файла).

Посмотрите на комментарии, которые я написал:

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

Вот почему content все еще пусто, когда вы входите в систему. узел еще не получил содержимое файла.

Это может быть решено путем перемещения console.log(content) внутри функции обратного вызова, сразу после content = data;, Таким образом, вы увидите журнал, когда узел завершит чтение файла и после content получает значение.

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

Синхронизация и асинхронное чтение файла:

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

Чит-узел доступен в файле read_file.

      var path = "index.html"

const readFileAsync = fs.readFileSync(path, 'utf8');
// console.log(readFileAsync)

используя простой readFileSync работает на меня.

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

Это просто потому, что узел асинхронный и он не будет ждать функцию чтения, и как только программа запустится, она будет поддерживать значение как неопределенное, что на самом деле верно, потому что нет значения, назначенного переменной содержимого. Для обработки мы можем использовать обещания, генераторы и т. Д. Мы можем использовать обещание таким образом.

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

Следующая функция будет работать для async завернуть или пообещать then цепи

const readFileAsync =  async (path) => fs.readFileSync(path, 'utf8');

Вы можете прочитать файл по

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

Добавив, вы можете написать в файл,

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

и даже связать это вместе

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

Грубо говоря, вы имеете дело с node.js, который по своей природе асинхронный.

Когда мы говорим об асинхронности, мы говорим о выполнении или обработке информации или данных, когда имеем дело с чем-то другим. Это не синоним параллели, пожалуйста, напомните.

Ваш код:

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

В вашем примере он сначала выполняет часть console.log, поэтому переменная 'content' не определена.

Если вы действительно хотите вывод, сделайте что-то вроде этого:

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

Это асинхронно. Будет трудно привыкнуть, но это то, что есть. Опять же, это грубое, но быстрое объяснение того, что такое асинхронность.

Мне нравится использовать fs-extra, потому что все функции обещаны прямо из коробки, поэтому вы можете использовать await. Итак, ваш код может выглядеть так:

      (async () => {
   try {
      const content = await fs.readFile('./Index.html');
      console.log(content);
   } catch (err) {
      console.error(err);
   }
})();
Другие вопросы по тегам