zoukankan      html  css  js  c++  java
  • 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('删除目录成功~~~')
                })
     
     
  • 相关阅读:
    I NEED A OFFER!
    水题 Codeforces Round #303 (Div. 2) A. Toy Cars
    模拟 HDOJ 5099 Comparison of Android versions
    模拟 HDOJ 5095 Linearization of the kernel functions in SVM
    贪心 HDOJ 5090 Game with Pearls
    Kruskal HDOJ 1863 畅通工程
    Kruskal HDOJ 1233 还是畅通工程
    并查集 HDOJ 1232 畅通工程
    DFS/并查集 Codeforces Round #286 (Div. 2) B
    水题 Codeforces Round #286 (Div. 2) A Mr. Kitayuta's Gift
  • 原文地址:https://www.cnblogs.com/carreyBlog/p/15548903.html
Copyright © 2011-2022 走看看