zoukankan      html  css  js  c++  java
  • 异步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);
            }
        });
    });
  • 相关阅读:
    共享纸巾更换主板代码分析 共享纸巾主板更换后的对接代码
    Python Django Ajax 传递列表数据
    Python Django migrate 报错解决办法
    Python 创建字典的多种方式
    Python 两个list合并成一个字典
    Python 正则 re.sub替换
    python Django Ajax基础
    Python Django 获取表单数据的三种方式
    python Django html 模板循环条件
    Python Django ORM 字段类型、参数、外键操作
  • 原文地址:https://www.cnblogs.com/zcy9838/p/11590087.html
Copyright © 2011-2022 走看看