• 006 I/O模块fs


    [a] fs文件系统

            在node中,与文件系统的交互时非常重要的,服务器的本质就是将本地的文件发送给远程的客户

            node通过fs模块实现与文件的交互

            fs是node中的核心模块(内部模块)

            fs系统最主要的操作就是文件的读取和写入

    [B] 同步和异步

            1. fs中所有的操作都有两种形式:同步和异步;异步的版本中函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。

            2. 同步文件会阻塞程序的运行,也就是除非文件操作完毕,否则不会执行下面的程序

            3. 异步文件不会阻塞程序的运行,而是在操作完成时通过回调函数返回。

            4. 建议大家使用异步方法,比起同步,异步方法性能更高,速度更快,而且没有阻塞。

                菜鸟教程学习:https://www.runoob.com/nodejs/nodejs-tutorial.html

      异步文件:

        全部读取:readFile        全部写入:writeFile

        部分读取:read          部分写入:write

      同步文件:

        全部读取:readFileSync      全部写入:writeFileSync

        部分读取:readSync        部分写入:writeSync

      1. fs.read() 读取文件部分内容(根据参数而定)

        语法

          fs.read(fd, buffer, offset, length, position, callback)

        参数:

          fd - 通过 fs.open() 方法返回的文件描述符。

          buffer - 数据写入的缓冲区。

          offset - 缓冲区写入的写入偏移量。

          length - 要从文件中读取的字节数。

          position - 文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。

          callback - 回调函数,有三个参数err, bytesRead, buffer, err 为错误信息, bytesRead 表示读取的字节数,buffer 为缓冲区对象。

        【注】:

          使用fs.read()方法读取文件内容时,首先需要一个文件描述符fd,fs.read()方法可以实现部分文件内容的读取。

          通过length和position参数可以指定读取文件内容的长度和读取内容的起始位置。

      2. fs.readFile() 读取文件全部内容

        语法:

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

        参数:

          filename —— 表示要读取的文件

          callback —— 回调函数有2个参数 (err, data),参数 data 是文件的内容。如果没有指定参数encoding, 则返回值为Buffer。

        【注】:

          fs.readFile()方法能且只能读取文件的全部内容,通过设置编码方式可以以字符串或Buffer的形式返回读结果。

      3. fs.read()和fs.readFile()方法的比较

        本质上讲,fs.readFile()方法是对fs.read()方法的进一步封装,fs.readFile()方法可以方便的读取文件的全部内容。

        相比fs.readFile()方法,使用fs.read()方法读取文件的全部内容可操作性要强很多。首先要用fs.stat判断文件的大小,然后使用fs.open()创建文件描述符,最后再使用fs.read()方法读取文件内容。

       
    [C] 文件的写入

                // 导入fs模块

                    var fs = require("fs");

            1.同步文件写入

                // 1. 打开文件
                var fd = fs.openSync("./Nodejs/filesystem/hello.txt", "w")
    
                // 2. 向文件中写入内容
                fs.writeSync(fd, "今天天气不错欸,我们去爬山吧~~~~", 5);
    
                // 3. 关闭文件
                fs.closeSync(fd);

            2. 异步文件写入

                // 1. 打开文件
                fs.open("./Nodejs/filesystem/hello.txt", "w", function(err, fd){
                    if(err){
                        return console.log(err);
                    }
    
                    // 2. 向文件中写入内容
                    fs.write(fd, "今天天气不错欸,我们去爬山吧~~~~", function(err){
                        if(!err){
                            console.log("文件写入成功!");
                        }
                    });
    
                    // 3. 关闭文件
                    fs.close(fd,function(er){
                        if(!er){
                            console.log("文件成功关闭~~~");
                        }
                    });
                })    
           
      3. 简单文件写入

                writeFile函数介绍:

                    fs.writeFile(fd, data, [option,] callback)

                        第一个参数:fd,文件名或文件描述符(结合fs.open)

                        第二个参数:data, 要写入文件的数据,可以是 String(字符串) 或 Buffer(缓冲) 对象

                        第三个参数:默认为:{encoding, mode, flag},一般只修改flag => {encoding:"utf8", mode:0666, flag:"a"}

                        第四个参数:回调函数,callback(err),err包含写入失败时的错误信息

                    【注】

                        1. 直接打开文件默认是 w 模式,所以如果文件存在,该方法写入的内容会覆盖旧的文件内容。

                        2. 该方法一般用在fs.open方法内部

                   异步写入

            fs.open("./Nodejs/input.txt", "w", function(err, fd){
                if(err){
                    return console.error(err);
                }
                for(var i = 0; i <= 3; i++){
                    fs.writeFile("./Nodejs/input.txt", `我是${i}个学生\n`, {encoding:"utf8", mode:0666, flag:"a"}, function(e){
                        if(e){
                            return console.log(e);
                        }
                    })
                    console.log("ok")
                }
            }) 

              等价于:

            var fs = require("fs");
            fs.writeFile("./Nodejs/filesystem/hello_1.txt", "这是简单文件的写入", function(err){
                if(err){
                    return err;
                }else{
                    console.log("文件写入成功~~")
                }
            })    

        同步写入

            var fd = fs.openSync('./simpleSync.txt', 'w')
            fs.writeFileSync(fd, '我是简单文件同步第一句!\n', function(err){
                if(err){
                    console.log(err)
                    return
                }
                console.log('写入文件成功!')
            })

            等价于

             var fs = require("fs");
            fs.writeFileSync("./Nodejs/filesystem/hello_1.txt", "这是简单文件的写入");
            4. 流式文件写入
        上述同步和异步以及简单文件写入都是一次性的完成写入操作,当写入的文件很大时,一次性写入会占用大量计算机内存,这样做不安全
        因此,对于大量数据的写入,我们采用流式文件写入,流式文件在读取和写入时会将大型文件分成若干小节,分小节逐步去读取和写入
             示例:
            // 流式文件写入
            var fs = require("fs");
            // 1. 创建一个写入文件流
            var ws = fs.createWriteStream("./Nodejs/filesystem/hel_2.txt");
            // 创建时间监听流的打开和关闭
            ws.once("open", function(){
                console.log("流打开了~~~");
            })
            ws.once("close", function(){
                console.log("流关闭了~~~");
            })
    
            // 2. 向文件中写入数据, 以ws.end();
            ws.write("我是熊大~\n");
            ws.write("我是熊二~\n");
            ws.write("我是熊三~\n");
            ws.write("我是熊四~\n");
            ws.end();

    [D] 文件的读取

            1. 同步文件的读取

            2. 异步文件的读取

            3. 简单文件的读取

                同步读取

                    示例:

            // 简单文件的同步读取
            var fs = require("fs");
            var rd = fs.readFileSync("./Nodejs/filesystem/input.txt");
             console.log(rd.toString());

                异步读取:

        示例:

            // 简单文件的异步读取
            var fs = require("fs");
            var rd = fs.readFile("./Nodejs/filesystem/input.txt", function(err,rd){
                if(err){
                    return err;
                }
                console.log(rd.toString());
            });

            4. 流式文件读取

                    示例:

             var fs = require("fs");
            // 1. 创建读取文件流
             var rs = fs.createReadStream("./Nodejs/filesystem/timg.jpg");
    
            // 2. 创建读取流的打开和关闭监听事件
            rs.once("open", function(){
                console.log("流打开了~~");
            })
            rs.once("close", function(){
                console.log("流关闭了~~");
            })
    
            // 3. 如果要读取一个可读流的数据,必须为这个可读流绑定一个data事件,data事件绑定完毕,他会自动读取数据
            // 每次读取的文件dt长度为65536
            rs.on("data", function(dt){
                console.log(dt);
            })
    
            // 简易写法
            var fs = require("fs");
            // 1. 创建一个可读流
            var rd = fs.createReadStream("./Nodejs/filesystem/timg.jpg");
            // 创建一个可写流
             var ws = fs.createWriteStream("./Nodejs/filesystem/mn.jpg");
            rd.pipe(ws);

    [E]  Stream(流)

            1. 简介

        Stream 是一个抽象接口,Node 中有很多对象实现了这个接口。例如,对http 服务器发起请求的request 对象就是一个 Stream,还有stdout(标准输出)。

            2. 所有的 Stream 对象都是 EventEmitter 的实例

        常用的事件有:

          data - 当有数据可读时触发。

          end - 没有更多的数据可读时触发。

          error - 在接收和写入过程中发生错误时触发。

          finish - 所有数据已被写入到底层系统时触发。

            3. 读取流 —— createReadStream

        1. 创建一个可读流    

          var rs = fs.createReadStream('./input.txt')

        2. 设置字符编码

          rs.setEncoding('UTF8');

                3. 创建流打开和关闭时的监听事件

          语法:

            rs.once('open', callback)
            rs.once('close', callback)

                4. 添加监听事件 - 在读取过程中的不同阶段添加自定义操作

          语法:

            rs.on(status, callback)

          参数:

            status: 读取过程中的状态

              data - 当有数据可读时触发。

              end - 没有更多的数据可读时触发。

              error - 在接收和写入过程中发生错误时触发。

              finish - 所有数据已被写入到底层系统时触发。

                          callback: 回调函数

                                即在指定状态时出发的事件

            4. 写入流 —— createWriteStream

        1. 创建一个写入流

          var ws = fs.createWriteStream('./outtxt.txt')

        2. 写入内容并设置写入时的字符集

          ws.write(txt, 'utf-8')

        3. 标记文件末尾

          ws.end()

        4. 添加监听事件

          // 写入文件结束后调用
          ws.on('finish', () => {
            console.log('写入文件结束~~~')
          })

          // 写入文件报错时调用

          writerStream.on('error', (err) => {
            console.log(err);
          });

           

      5. 管道流 —— pipe

          管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中

          通常用于复制文件,或部分复制文件

        1. 创建一个可读流

          var rs = fs.createReadStream('input.txt');

        2. 创建一个可写流

          var ws = fs.createWriteStream('output.txt');

        3. 管道读写操作

          // 读取 input.txt 文件内容,并将内容写入到 output.txt 文件中
          rs.pipe(ws);

        

      6. 链式流 —— pipe

          链式是通过连接输出流到另外一个流并创建多个流操作链的机制。链式流一般用于管道操作。

        1. 示例

          // 压缩 input.txt 文件为 input.txt.gz
          fs.createReadStream('input.txt')
          .pipe(zlib.createGzip())
          .pipe(fs.createWriteStream('input.txt.gz'));

          注:

            zlib需要先导入

              var zlib = require('zlib');

                2. 则上述的文件复制工作可简化为一个链式流

                    fs.createReadStream('./inputStream.txt').pipe(fs.createWriteStream('./outtxt.txt'))

     [F] 获取文件信息 —— stat

            1. 语法

                    fs.stat(path, callback)

                参数说明:

                    path - 文件路径。

                    callback - 回调函数,带有两个参数如:(err, stats), stats 是 fs.Stats 对象。

                stats类中的方法有:

                    stats.isFile()              如果是文件返回 true,否则返回 false。

                    stats.isDirectory()         如果是目录返回 true,否则返回 false。

                    stats.isBlockDevice()       如果是块设备返回 true,否则返回 false。

                    stats.isCharacterDevice()   如果是字符设备返回 true,否则返回 false。

                    stats.isSymbolicLink()      如果是软链接返回 true,否则返回 false。

                    stats.isFIFO()              如果是FIFO,返回true,否则返回 false。FIFO是UNIX中的一种特殊类型的命令管道。

                    stats.isSocket()            如果是 Socket 返回 true,否则返回 false。

            2. 示例:

                var fs = require('fs');
                fs.stat('./data.js', function (err, stats) {
                    if(err){
                        console.log(err)
                        return
                    }
                    console.log(stats.isFile());         //true
                })

    [G] 删除文件 —— unlink

            1. 语法

                    fs.unlink(path, callback)

                参数说明:

                    path - 文件路径。

                    callback - 回调函数,没有参数。

            2. 示例代码

                fs.unlink('./data.js', (err) => {
                    if(err){
                        console.log(err)
                        console.log('删除文件失败~~~')
                        return
                    }
                    console.log('删除文件成功~~~')
                })

    [H] 创建目录 —— mkdir

            1. 语法

                    fs.mkdir(path[, options], callback)

                参数说明:

                    path - 文件路径。

                    options 参数可以是:

                        recursive - 是否以递归的方式创建目录,默认为 false。

                        mode - 设置目录权限,默认为 0777。

                    callback - 回调函数,没有参数。

            2. 示例

                fs.mkdir('./Carrey', (err) => {
                    if(err){
                        console.log(err)
                        console.log('创建文件夹失败了~~~')
                        return
                    }
                    console.log('创建文件夹成功~~~')
                })

    [ I ]读取目录 —— readdir

            1. 语法

                    fs.readdir(path, callback)

                参数使用说明如下:

                    path - 文件路径。

                    callback - 回调函数,回调函数带有两个参数err, files,err 为错误信息,files 为 目录下的文件数组列表。

            2. 示例

                fs.readdir('./Carrey', (err, files) => {
                    if(err){
                        console.log(err)
                        console.log('读取文件失败了~~~')
                        return
                    }
                    console.log(files)
                })

    [J] 删除目录 —— rmdir

            1. 语法

                    fs.rmdir(path, callback)

                参数使用说明如下:

                    path - 文件路径。

                    callback - 回调函数,没有参数。

                注:

                    该方法只能删除空的目录,当目录内部不为空时,会报错

            2. 示例

                fs.rmdir('./Carrey', (err) => {
                    if(err){
                        console.log(err)
                        console.log('删除目录失败~~~')
                        return
                    }
                    console.log('删除目录成功~~~')
                })
     
     
  • 相关阅读:
    windows cmd 快速编辑 模式
    navicat 15 学习版
    mysql 参数设置
    cat 高亮
    基本概念(4)——调试器
    基本概念(3)——cmake、qmake
    基本概念(2)——make、ninja、nmake、jom
    基本概念(1)——编译器
    LCP 19. 秋叶收藏集
    leetcode 117 填充每个节点的下一个右侧节点指针 II
  • 原文地址:https://www.cnblogs.com/carreyBlog/p/15548903.html
Copyright © 2020-2023  润新知