node.js读取文件

node.js内置了异步读取文件的模块,可以很方便地读取文件的数据。先创建三个txt文档,在根目录下创建一个readFile.js

输入以下代码,然后在vscode的终端中输入node read(按Tab键自动生成当前js文件所在路径),回车后执行,可以看到输出的读取1.txt的结果

const fs = require('fs') //操作文件的对象
const path = require('path') //路径对象

 fs.readFile(path.join(__dirname, './files/1.txt'), 'utf-8', (err, dataStr) => {
  if (err) throw err; //错误信息
  console.log(dataStr) //读取的数据
}) ;

现在假如1.txt里的内容超级多,而2.txt里只有一条数据,如果需求是按照编号顺序依次读取文件数据,那么就应该当1.txt返回数据后再读2.txt。可是fs是异步读取数据,那么当1.txt还未返回结果的同时,2.txt可能已经读取完成并返回了结果。如下代码看起来是先执行1.txt,可输出结果必然是先打印2.txt的数据再打印1.txt的数据。

const fs = require('fs')
const path = require('path')

function readFile(path, coding,callback){
  fs.readFile(path, coding, (err, dataStr) => {
    callback(err==null?dataStr:err);  
  }) ;  
}

readFile(
    path.jon(__dirname, './files/1.txt'),
    'utf-8',
    (msg)=>{
      console.log(msg);      
});

readFile(
    path.jon (__dirname, './files/2.txt'),
    'utf-8',
    (msg)=>{
      console.log(msg);      
});

现在又假如有10个文件需要按顺序读取,则你只能在前一个文件读取完成输出数据后再读取后面的文件

const fs = require("fs");
const path = require("path");

function readFile(path, coding, callback) {
    fs.readFile(path, coding, (err, dataStr) => {
        callback(err == null ? dataStr : err);
    });
}

readFile(
    path.join(__dirname, './files/1.txt'),
    'utf-8',
    (msg) => {
        console.log(msg);

        readFile(
            path.join(__dirname, './files/2.txt'),//第一个文件读取完后读取第二个文件
            'utf-8',
            (msg) => {
                console.log(msg);

                readFile(
                    path.join(__dirname, './files/3.txt'),//第二个文件读取完后读取第三个文件
                    'utf-8',
                    (msg) => {
                        console.log(msg);

                        readFile(
                            path.join(__dirname, './files/4.txt'),
                            'utf-8',
                            (msg) => {
                                console.log(msg);

                                readFile(
                                    path.join(__dirname, './files/5.txt'),
                                    'utf-8',
                                    (msg) => {
                                        console.log(msg);

                                        readFile(
                                            path.join(__dirname, './files/6.txt'),
                                            'utf-8',
                                            (msg) => {
                                                console.log(msg);

                                                readFile(
                                                    path.join(__dirname, './files/7.txt'),
                                                    'utf-8',
                                                    (msg) => {
                                                        console.log(msg);

                                                        readFile(
                                                            path.join(__dirname, './files/8.txt'),
                                                            'utf-8',
                                                            (msg) => {
                                                                console.log(msg);

                                                                readFile(
                                                                    path.join(__dirname, './files/9.txt'),
                                                                    'utf-8',
                                                                    (msg) => {
                                                                        console.log(msg);

                                                                        readFile(
                                                                            path.join(__dirname, './files/10.txt'),
                                                                            'utf-8',
                                                                            (msg) => {
                                                                                console.log(msg);
                                                                            });
                                                                    });
                                                            });
                                                    });
                                            });
                                    });
                            });
                    });
            });
    });

以上代码叫做回调地狱

ES6的Promise异步对象

这个对象提供了在构造函数中传递一个自定义的函数,当实例化Promise对象的同时就会异步执行你传递进去的函数。Promise自身还提供一个then函数,你可以向该方法传递两个回调,一个代表执行成功后的回调(resolve),另一个代表执行失败后的回调(reject)。

function readFile(path) {
      const fs = require('fs');
      const dirPath = require('path');
      //实例化Promise时传递一个读取文件的函数让Promise对象去异步执行
      //该函数接收两个回调函数,在读取文件失败或成功时将信息传递给回调函数,让他们输出结果
      var promise = new Promise(function (resolve, reject) {
            fs.readFile(dirPath.join(__dirname, path), "utf-8", (err, data) => {
                  if (err) return reject(err); //如果读取失败则将错误信息传递给回调函数且立即返回
                  resolve(data); 
            });
      });
      //实例化Promise时就会异步执行你传递的函数
      //因为该函数是异步执行,所以下面的return promise会同一时间运行,
      //也即异步执行你传递的函数时也会执行下面的代码,返回一个promise对象到外部
      return promise;
}

//外部调用readFile得到promise对象后调用它的then方法
//then方法接收两个函数作为参数,它会把这两个函数传递给实例化Promise对象时的你传递的函数里:new Promise(function(resolve, reject))
readFile('./files/1.txt').then(
      (data) => { console.log(data) },  
      (err) => { console.log(err) }
);

Promise对象并不能减少大量回调的代码量,但通过它可以完成针对读取文件的不同需求。

需求1:需要读取3个文件,按顺序从1到3逐一读取,如果前面的文件读取失败也不影响后续文件的读取

eadFile('./files/11.txt').then(
      function(data){
            console.log(data);
            return readFile('./files/2.txt');
      },
      function(err){
            console.log(err); //第一个文件已经读取失败则直接进入错误处理,输出错误信息
            return readFile('./files/2.txt');//继续调用读取文件的函数
      }     
).then(
      function(data){
            console.log(data);
            return readFile('./files/3.txt');
      },
      function(err){
            console.log(err);
            return readFile('./files/3.txt');
      }     
).then(
      function(data){
            console.log(data);
      },
      function(err){
            console.log(err);
      }      
);

需求2:需要读取3个文件,按顺序从1到3逐一读取,如果前面的文件读取失败则不再需要继续读取后面的文件,此时不能在err里直接输出错误信息并不再调用读取文件的函数,这样做会出现问题,解决办法是在链式调用的末尾使用catch方法

readFile('./files/11.txt').then(
      function (data) {
            console.log(data);
            return readFile('./files/2.txt');
      }
).then(
      function (data) {
            console.log(data);
            return readFile('./files/3.txt');
      }
).then(
      function (data) {
            console.log(data);
      }
).catch(function (err) {
      console.log(err.message);
});

  

Javascript - 学习总目录

Javascript - 异步操作和读取文件的更多相关文章

  1. Win10系列:JavaScript写入和读取文件

    正如上面的内容中所提到的,文件保存选取器用于保存文件,通过Windows.Storage.Pickers命名空间中的FileSavePicker类的pickSaveFileAsync函数可以向指定的文 ...

  2. JS读取文件,Javascript之文件操作 (IE)

    一.功能实现核心:FileSystemObject 对象      要在javascript中实现文件操作功能,主要就是依靠FileSystemobject对象. 二.FileSystemObject ...

  3. 通过 File API 使用 JavaScript 读取文件

    原文地址:http://www.html5rocks.com/zh/tutorials/file/dndfiles/ 简介 HTML5 终于为我们提供了一种通过 File API 规范与本地文件交互的 ...

  4. javascript:FileReader对象(读取文件)

    FileReader对象 1.检测浏览器对FileReader的支持 1 if(window.FileReader) { 2 var fr = new FileReader(); 3 // add y ...

  5. javascript ActiveXObject FileSystemObject 对象,创建、复制、删除、读取文件等

    Javascript是网页制作中离不开的脚本语言,依靠它,一个网页的内容才生动活泼.富有朝气.但也许你还没有发现并应用它的一些更高级的功能吧?比如,对文件和文件夹进行读.写和删除,就象在VB.VC等高 ...

  6. File API 读取文件小结

    简单地说,File API只规定怎样从硬盘上提取文件,然后交给在网页中运行的JavaScript代码. 与以往文件上传不一样,File API不是为了向服务器提交文件设计的. 关于File API不能 ...

  7. 使用 JavaScript File API 实现文件上传

    概述 以往对于基于浏览器的应用而言,访问本地文件都是一件头疼的事情.虽然伴随着 Web 2.0 应用技术的不断发展,JavaScript 正在扮演越来越重要的角色,但是出于安全性的考虑,JavaScr ...

  8. 用仿ActionScript的语法来编写html5——第九篇,仿URLLoader读取文件

    第九篇,仿URLLoader读取文件 先看看最后的代码 function readFile(){ urlloader = new LURLLoader(); urlloader.addEventLis ...

  9. HTML5 文件域+FileReader 读取文件(一)

    在HTML5以前,HTML的文件上传域的功能具有很大的局限性,这种局限性主要体现在如下两点: 每次只能选择一个文件进行上传 客户端代码只能获取被上传文件的文件路径,无法访问实际的文件内容 一.File ...

随机推荐

  1. synchronized锁机制(六)

    前言 1.理解同步关键词synchronized 2.同步方法与同步代码块的区别 3.理解锁的对象this 脏读 一个常见的概念.在多线程中,难免会出现在多个线程中对同一个对象的实例变量进行并发访问的 ...

  2. Git的使用(六)

    前言 版本管理工具总结: 开发团队项目,对项目的版本进行管理. 使用过的版本管理工具: TFS.SVN与Git. TFS:管理项目,通过visual Studio管理源码,拉取分支,提交代码等.也可以 ...

  3. my.ini修改后启动失败

    修改之后ini文件后不要直接关闭在记事本里点击另存为,编码选择为ANSI编码格式,再保存就行了

  4. Beautiful Soup4.4.0中文官方文档!最权威的参考---中文官方文档

    最好用的解析库Beautiful Soup 解析库-----中文官方文档 https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/

  5. Webmin 远程命令执行漏洞(CVE-2019-15107)

    影响版本 Webmin 1.920及以下版本 poc地址 https://github.com/Mr-xn/Penetration_Testing_POC/tree/master/CVE-2019-1 ...

  6. Django debug page XSS漏洞(CVE-2017-12794)

    影响版本:1.11.5之前的版本 访问http://your-ip:8000/create_user/?username=<script>alert(1)</script>创建 ...

  7. Optional解决空指针

    Java 8 Optional 类 Java 8 新特性 Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. O ...

  8. linux中的dhcp

    目录 一.DHCP服务 二.DHCP的租约过程 三.使用DHCP动态配置主机地址 四.安装DHCP服务器 一.DHCP服务 ① DHCP (Dynamic HostConfiguration Prot ...

  9. Spring对Controller、Service、Dao进行Junit单元测试总结

    测试类注解 @RunWith(SpringRunner.class) @SpringBootTest(classes={DemoApplication.class}) 以Controller层的的单元 ...

  10. 对抗防御之对抗样本检测(一):Feature Squeezing

    引言 在之前的文章中,我们介绍了对抗样本和对抗攻击的方法.在该系列文章中,我们介绍一种对抗样本防御的策略--对抗样本检测,可以通过检测对抗样本来强化DNN模型.本篇文章论述其中一种方法:feature ...