• 异步I/O


    异步I/O  input/output
    1.文件操作
    2.网络操作
     
     在浏览器中也存在异步操作:
    1.定时任务
    2.事件处理
    3.Ajax回调处理
     
     js的运行是单线程的
    引入事件队列机制
     
    Node.js中的事件模型与浏览器中的事件模型类似
    单线程+事件队列(JS的运行是单线程的,但是Node.js的环境和浏览器的环境是多线程的)
     
    Node.js中异步执行的任务:
    1.文件I/O
    2.网络I/O
     
    Node.js是基于回调函数的编码风格

     1.文件操作

    const fs = require('fs');
    
    //异步操作
    //一般回调函数的第一个参数是错误对象,如果err为null,表示没有错误,否则表示报错了
    //..表示上级目录,.表示当前目录
    //异步的执行结果是:先输出1 再输出3 最后输出2
    //因为第二个异步的任务会进入到事件队列中,当主线程代码都执行完了,才能空闲去事件队列中把任务取出来执行
    console.log(1);
    fs.stat('../buffer',(err,stat) => {
        if(err) return;
        if(stat.isFile()){
            console.log('文件');
        }else if(stat.isDirectory()){
            console.log('目录');
        }
        console.log(stat);
        console.log(2);
    });
    console.log(3);

    //异步操作是没有返回值的,只有同步操作才有返回值
    //同步操作
    //执行顺序肯定是:1 ret 2
    console.log(1);
    let ret = fs.statSync('./01.js');
    console.log(ret);
    console.log(2);

    /**
     * 读文件操作
     */
    const fs = require('fs');
    const path = require('path');
    
    //异步操作
    let strpath = path.join(__dirname,'01.js');   //__dirname表示当前文件夹的绝对路径
    //如果有第二个参数并且是编码,那么回调函数获取到的数据就是字符串
    //如果没有第二个参数,那么得到的就是Buffer实例对象
    fs.readFile(strpath,(err,data) => {
        if(err) return;
        console.log(data.toString());   //不调用toString(),则打印出来的是Buffer对象
    });
    
    //同步操作
    let ret = fs.readFileSync(strpath,'utf8');
    console.log(ret);
    
    /**
     * 写文件操作
     */
    //异步操作
    //注意:写入的内容会覆盖掉文件里原来的内容
    fs.writeFile(strpath,'hello world','utf8',(err) => {
        if(err) throw err;
        console.log('文件写入成功!');
    });
    
    let data = Buffer.from('hi');
    fs.writeFile(strpath,data,'utf8',(err) => {
        if(err) throw err;
        console.log('文件写入成功!');
    });
    
    //同步操作
    let ret = fs.writeFileSync(strpath,'tom and jerry','utf8');
    console.log(ret);    //返回undefined
    /**
     * 大文件操作(流式操作)
     * fs.createReadStream(path[, options])
     * fs.createWriteStream(path[, options])
     */
    const path = require('path');
    const fs = require('fs');
    
    let spath = path.join('E://','test.zip');
    let dpath = path.join('E://','file.zip');
    console.log(spath);
    
    let readStream = fs.createReadStream(spath);
    let writeStream = fs.createWriteStream(dpath);
    //console.log(writeStream);
    
    //基于事件的处理方式
    let num = 1;
    readStream.on('data',(chunk) => {
        num++;
        writeStream.write(chunk);
    });
    readStream.on('end',() => {
        console.log('文件处理完成'+num);
    });
    //============================================================
    //pipe的作用直接把输入流和输出流链接到一块
    //readStream.pipe(writeStream);
    fs.createReadStream(spath).pipe(fs.createWriteStream(dpath));

    2.目录操作

    /**
     * 目录操作:
     * 1.创建目录
     * fs.mkdir(path[, options], callback)
     * fs.mkdirSync(path[, options])
     * 2.读取目录
     * fs.readdir(path[, options], callback)
     * fs.readdirSync(path[, options])
     * 3.删除目录
     * fs.rmdir(path[, options], callback)
     * fs.rmdirSync(path[, options])
     */
    const path = require('path');
    const fs = require('fs');
    //创建目录
    //异步操作
    fs.mkdir(path.join(__dirname,'abc'),(err) => {
        console.log(err);   //若没有错误,则返回null
    });
    
    //同步操作
    fs.mkdirSync(path.join(__dirname,'hello'));
    
    //读取目录
    //let pathdir = path.join(__dirname,'../es6');
    let pathdir = __dirname
    //异步操作
    fs.readdir(pathdir,(err,files) => {
        if(err) return;
        files.forEach((item,index) => {
            fs.stat(path.join(pathdir,item),(err,stat) => {
                if(stat.isFile()){
                    console.log(item,'文件');
                }else if(stat.isDirectory()){
                    console.log(item,'目录');
                }
            });
        });
    });
    
    //同步操作
    let files = fs.readdirSync(pathdir);
    files.forEach((item) => {
        fs.stat(path.join(pathdir,item),(err,stat) => {
            if(stat.isFile()){
                console.log(item,'文件');
            }else if(stat.isDirectory()){
                console.log(item,'目录');
            }
        });
    });
    
    //删除目录
    //异步操作
    fs.rmdir(path.join(__dirname,'abc'),(err) => {
        console.log(err);
    });
    
    //同步操作
    let ret = fs.rmdirSync(path.join(__dirname,'hello'));
    console.log(ret);

     3.初始化目录结构

    /**
     * 文件操作案例(初始化目录结构)
     */
    const path = require('path');
    const fs = require('fs');
    
    //创建的根目录的路径
    let root = 'E:\';
    //用反引号
    let fileContent = `
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <div>welcome!</div>
    </body>
    </html>
    `;
    //初始化数据
    let initData = {
        projectName : 'mydemo',
        data :[{
            name : 'img',
            type : 'dir'
        },
        {
            name : 'css',
            type : 'dir'
        },
        {
            name : 'js',
            type : 'dir'
        },
        {
            name : 'index.html',
            type : 'file'
        }]
    };
    //创建项目跟路径
    fs.mkdir(path.join(root,initData.projectName),(err) => {
        if(err){
            console.log('创建失败!'); return;
        }
        //创建子目录和文件
        initData.data.forEach((item) => {
            if(item.type == 'dir'){
                //创建子目录
                fs.mkdirSync(path.join(root,initData.projectName,item.name));
            }else if(item.type == 'file'){
                //创建文件并写入内容:若没有这个文件,则自动创建然后写入内容
                fs.writeFileSync(path.join(root,initData.projectName,item.name),fileContent);
            }
        });
    });
  • 相关阅读:
    Java开发中的23种设计模式详解(转)
    主表和从表
    MyBatis开发中解决返回字段不全的问题
    个人常用配置文件解析
    SpringMVC+MyBatis开发中指定callSettersOnNulls,可解决返回字段不全的问题
    mybatis之sql执行有数据但返回结果为null
    Hadoop window win10 基础环境搭建(2.8.1)
    什么水平算精通C++ Builder?
    Delphi中取得汉字的首字母(十分巧妙)
    全部的Windows消息对应值
  • 原文地址:https://www.cnblogs.com/zcy9838/p/11590087.html
Copyright © 2020-2023  润新知