Javascript 从fs.readFile获取数据

Javascript 从fs.readFile获取数据,javascript,node.js,Javascript,Node.js,日志未定义,为什么?要详细说明@Raynos所说的内容,您定义的函数是一个异步回调函数。它不会立即执行,而是在文件加载完成后执行。调用readFile时,会立即返回控件并执行下一行代码。因此,当您调用console.log时,您的回调尚未被调用,并且此内容尚未设置。欢迎使用异步编程 示例方法 var content; fs.readFile('./Index.html', function read(err, data) { if (err) { throw err;

日志
未定义
,为什么?

要详细说明@Raynos所说的内容,您定义的函数是一个异步回调函数。它不会立即执行,而是在文件加载完成后执行。调用readFile时,会立即返回控件并执行下一行代码。因此,当您调用console.log时,您的回调尚未被调用,并且此内容尚未设置。欢迎使用异步编程

示例方法

var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
});
console.log(content);
或者更好,如Raynos示例所示,将调用封装在函数中,并传入自己的回调。(显然这是更好的做法)我认为,养成在接受回调的函数中包装异步调用的习惯将为您节省很多麻烦和混乱的代码

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

实际上,这有一个同步功能:

异步的
fs.readFile(文件名,[编码],[回调])

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

回调传递了两个参数(err,data),其中data是文件的内容

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


同步的
fs.readFileSync(文件名,[encoding])

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

如果指定了编码,则此函数返回一个字符串。否则它将返回一个缓冲区


如前所述,
fs.readFile
是一个异步操作。这意味着当你告诉节点读取一个文件时,你需要考虑它需要一些时间,同时,节点继续运行下面的代码。在您的例子中,它是:
console.log(content)

这就像在长途旅行中发送部分代码(比如读取一个大文件)

看看我写的评论:

var text = fs.readFileSync('test.md','utf8')
console.log (text)
这就是为什么当您登录时,
内容
仍然是空的。节点尚未检索文件的内容

这可以通过将
console.log(content)
移动到回调函数中
content=data之后来解决。这样,当节点读取完文件并在
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);
用于同步调用文件,
不进行编码,将输出显示为缓冲区。

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

var data = fs.readFileSync('tmp/reltioconfig.json','utf8');
节点欺骗可在。

使用ES7的承诺 与mz/fs的异步使用 该模块提供核心节点库的预期版本。使用它们很简单。首先安装库

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

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

const fs = require('mz/fs');
fs.readFile('./Index.html').then(contents => console.log(contents))
  .catch(err => console.error(err));
您可以通过以下方式读取文件:

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());
});
添加您可以写入文件的

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();
  });
};
这仅仅是因为节点是异步的,它不会等待read函数,程序启动后,它会将该值作为未定义值进行控制台处理,这实际上是真的,因为没有为内容变量分配值。 为了处理这些问题,我们可以使用承诺、发电机等。 我们可以这样使用承诺

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

粗略地说,您正在处理node.js,它本质上是异步的

当我们谈论异步时,我们谈论的是在处理其他事情的同时进行或处理信息或数据。这不是平行的同义词,请注意

您的代码:

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.
})
对于您的示例,它基本上首先执行console.log部分,因此未定义变量“content”

如果确实需要输出,请执行以下操作:

var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
});
console.log(content);
这是异步的。这很难适应,但事实就是这样。
同样,这是对什么是异步的粗略但快速的解释。

使用内置的promisify库(Node 8+)使这些旧回调函数更加优雅

var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
    console.log(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!");
      });
    });
  }
这条线可以用

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

以下函数适用于
async
wrap或promise
then

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

使用简单的
readFileSync
对我很有用。

非常感谢,如果我得了15分,我会投票支持你的答案:)嗨,在你代码的第一行,
function readContent(callback)
,callback
是保留字吗?我的意思是,这是实现自定义函数回调的标准方法吗?我刚开始学习node。你好,Amal。Callback只是传递给其函数的参数,它可以是
event
c
或您喜欢的任何名称-它在Javascript中不是保留字,我假设它也扩展到Node.js。
readContent(函数(err,content)
在将函数用作参数时,给了我一个语法错误。快速提问,readFile同步版本中返回的缓冲区有什么用途?如果我同步读取一个文件,但没有通过任何编码,它会打印缓冲区,我如何使用它?谢谢。我最近有过这方面的经验。假设我们的缓冲区是
data
if(Buffer.isBuffer(data){result=data.toString('utf8');}
现在,我们已经将缓冲区转换为可读文本。这对于读取纯文本文件或根据格式类型测试文件非常有用。例如,我可以尝试/catch查看它是否是JSON文件;但只有在缓冲区转换为文本后才可以。查看此处了解更多信息:据我所知,缓冲区是八位字节流,对sen非常有用“一块一块”的数据您一定已经看到缓冲区类似于
AF 42 F1
。对于客户机-服务器-客户机通信来说非常实用。同步I/O有它的位置-如果您使用的是小型构建系统或工具,这很好。在更大的系统或服务器应用程序上,最佳做法是避免它。不是所有的东西都是web服务器。horrib没有什么可怕的关于在服务器开始接收请求之前,为一次性调用使用同步版本的方法。任何使用Node的人都应该在使用它之前真正了解原因。在对它进行大量博客之前,绝对要这样做。例如,你必须
var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
});
console.log(content);
var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
    console.log(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!");
      });
    });
  }
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);
  }
}
const content = fs.readFileSync('./Index.html', 'utf8');
console.log(content);
const readFileAsync =  async (path) => fs.readFileSync(path, 'utf8');
var path = "index.html"

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