从fs.readFile获取数据

kar*_*una 277 javascript node.js

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

记录undefined,为什么?

Mat*_*sch 320

要详细说明@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);
}
Run Code Online (Sandbox Code Playgroud)

或者更好的是,正如Raynos示例所示,将您的调用包装在函数中并传入您自己的回调.(显然这是更好的做法)我认为养成将异步调用包装在需要回调的函数中的习惯将为您节省很多麻烦和杂乱的代码.

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

doSomething (function doSomethingAfter(err, result) {
    // process the async result
});
Run Code Online (Sandbox Code Playgroud)

  • 并非所有东西都是Web服务器.在服务器开始接受请求之前,使用同步版本的方法进行一次性调用并不可怕.任何使用Node的人都应该在使用之前了解原因.绝对是在关于它的咆哮博客之前. (19认同)
  • 您必须在文件名后添加`'utf8'作为附加参数,否则它将返回一个缓冲区。参见:/sf/ask/641811621/ (3认同)
  • 同步 I/O 有它的位置——如果你在做一个小型的构建系统或工具,这很好。在较大的系统或服务器应用程序上,最佳做法是避免它。 (2认同)

Log*_*gan 229

实际上有一个同步功能:

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

异步

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

异步读取文件的全部内容.例:

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

回调传递两个参数(错误,数据),其中data是文件的内容.

如果未指定编码,则返回原始缓冲区.


同步

fs.readFileSync(filename, [encoding])

fs.readFile的同步版本.返回名为filename的文件的内容.

如果指定了encoding,则此函数返回一个字符串.否则它返回一个缓冲区.

var text = fs.readFileSync('test.md','utf8')
console.log (text)
Run Code Online (Sandbox Code Playgroud)

  • 我最近有这方面的经验.假设我们的缓冲区是`data`.`if(Buffer.isBuffer(data){result = data.toString('utf8');}`现在我们已经将缓冲区转换为可读文本.这对于读取纯文本文件或根据格式类型测试文件非常有用.可以做一个try/catch来查看它是否是一个JSON文件;但只有在缓冲区转换为文本之后.在这里查看更多信息:http://nodejs.org/api/buffer.html (12认同)

Ray*_*nos 101

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)
})
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢,如果我有15分,我会投票给你答案:) (6认同)
  • 嗨Amal.回调只是传递给他的函数的参数,它可以是`event`或`c`或你喜欢的任何名字 - 它不是Javascript中的保留字,我会假设同样扩展到Node.js. (3认同)

Eva*_*oll 62

在ES7中使用Promise

与mz/fs异步使用

mz模块提供了核心节点库的promisified版本.使用它们很简单.首先安装库...

npm install mz
Run Code Online (Sandbox Code Playgroud)

然后...

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

或者,您可以在异步函数中编写它们:

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

  • 这是未来,应该受到大家的高度赞扬:)谢谢 (6认同)
  • 看起来很有趣 一个错字:'console.error(catch)'应该是'console.error(错误)'我认为'). (2认同)
  • 如果您不想添加额外的包,请尝试下面的@doctorlee解决方案 (2认同)

小智 14

var data = fs.readFileSync('tmp/reltioconfig.json','utf8');
Run Code Online (Sandbox Code Playgroud)

使用它来同步调用文件,而不将其显示输出编码为缓冲区.

  • 您需要在代码块之前添加一个空行,以便进行漂亮的打印。 (2认同)

Ara*_*vin 8

这条线会工作,

const content = fs.readFileSync('./Index.html', 'utf8');
console.log(content);
Run Code Online (Sandbox Code Playgroud)


Tai*_*ism 7

如上所述,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);
Run Code Online (Sandbox Code Playgroud)

这就是为什么content在你登录时它仍然是空的.节点尚未检索文件的内容.

这可以通过console.log(content)在回调函数内部移动来解决content = data;.这样,当节点完成读取文件并content获取值后,您将看到日志.


Zee*_*mon 7

同步和异步文件读取方式:

//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);
Run Code Online (Sandbox Code Playgroud)

节点作弊在read_file中可用.


小智 7

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!");
      });
    });
  }
Run Code Online (Sandbox Code Playgroud)

  • 请不要仅仅在您的答案中添加代码...说明为什么它与众不同以及它如何解决问题。 (3认同)

Sup*_*ova 7

var path = "index.html"

const readFileAsync = fs.readFileSync(path, 'utf8');
// console.log(readFileAsync)
Run Code Online (Sandbox Code Playgroud)

对我来说使用简单的readFileSync作品。


Nou*_*had 6

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

这是因为节点是异步的,它不会等待读取函数,并且一旦程序启动,它就会将值控制台为未定义,这实际上是正确的,因为没有为内容变量分配值。我们可以使用 Promise、Generator 等来处理。我们可以以这种方式使用 Promise。

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.
})
Run Code Online (Sandbox Code Playgroud)


Mas*_*ali 5

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());
});
Run Code Online (Sandbox Code Playgroud)


Dom*_*nic 5

使用内置的Promisify库(节点8+)可以使这些旧的回调函数更加美观。

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 不使用同步版本是重点,您应该处理调用它时的错误 (3认同)

rab*_*rab 5

以下函数适用于async包装或承诺then

const readFileAsync =  async (path) => fs.readFileSync(path, 'utf8');
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

479147 次

最近记录:

6 年,5 月 前