Получить данные из 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
});
На самом деле есть синхронная функция для этого:
Асинхронный
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);
}
})();