Node模块创建及使用,文件操作,IO交互,URL解析

2016-09-13  本文已影响0人  程序员有话说

目录

一、模块创建以及使用

核心模块部分在Node源代码的编译过程中,编译进了二进制执行文件。在Node进程启动时,部分核心模块就被直接加载进内存中,所以这部分核心模块引入时,文件定位和编译执行这两个步骤可以省略掉,并且在路径分析中优先判断,所以他的加载速度是最快的。

//mymodule.js
//使用exports向外部暴露方法
var name;
exports.setName=function(isname) {
    name = isname;
}
exports.sayNanme=function (){
    console.log('hello my name is '+name);
}
//getmymodule.js
var myModule =require('./mymodule');
myModule.setName('AngelaMuller');//调用模块中方法设置属性
myModule.sayNanme();//调用方法

使用:

muller@ubuntu:~/node$ node getmymodule.js
hello my name is AngelaMuller

第二种方式

//mymodule.js
module.exports =  function (name){
    this.name = name;
    this.sayhello = function(){
        console.log('hello world!'+this.name);
    }
};
//getmymodule.js
var person  = require('./mymodule');
var oneper = new person('AngelaMuller');
oneper.sayhello();

使用:

muller@ubuntu:~/node$ node getmymodule.js
hello world!AngelaMuller

定义模块:singleobejct.js

function hello(){
    var name;
    this.setName=function(thyName){
        name=thyName;
    }
    this.sayHello=function(){
        console.log('hello '+name);
    }
}
//exports.hello=hello;
module.exports=hello;    // 定义的方法添加   (简单的方式)

引入模块使用:getSingleObject.js

var hello=require('./singleobject');
var he=new hello();
he.setName('marico');  //实例化第一个实例
he.sayHello();
var he2=new hello();  //实例化第二个实例
he2.setName('yfc');
he2.sayHello()

结果输出:

[root@localhost nodejs]# node getSingleObject.js 
hello marico
hello yfc

繁琐:exports.hello=hello; //使用这种方式加载在对象中时,在调用使用时比较繁琐
引入:require("./singleobject").hello;

二、文件操作

node.js模块是文件操作的封装,它提供了文件的读取,写入,更名,删除,遍历目录,链接POSIX文件系统操作。与其他模块不同的是,fs模块中所有的操作都提供了异步和同步两个版本,例如,读取文件内容函数异步方法,readFile(),同步方法readFileSync().

  • 同步方式的文件系统调用会导致阻塞,由于Node.js是单线程的,直到文件调用完成后,控制权才会被放回主线程,这也就导致了后台其他线程池中的很多线程不能够执行,从而导致Node.js中一定程度的性能问题。因此应该尽可能的减少使用同步方式的文件系统的方法调用。
  • 异步调用会被主线程放置在事件队列中以备随后运行,这使得调用能够融入Node.js中的事件模型。但在执行代码时,就会变得有点棘手,因为事件并不能在预期的时候完成,这就需要有一个callback函数来规定当调用完成时需要完成的事。(这里可以去深入了解下Node.js的事件队列)

注: 同步方法返回true/false,异步方法callback仅仅只有一个err对象表示是否删除成功。

同步读取
//引入fs模块
var fs=require('fs');
fs.readFile('content.txt','UTF-8',function(err,data){
    if(err){
        console.log(err);
    }else{
        console.log(data);
    }
});

//没有回调函数
try{
    var data=fs.readFileSync('content.txt','UTF-8');
    console.log(data+"同步式读取");
}catch(e){
    console.log(e)
}

content.txt 内容

Node.js的文件系统的Api   AngelaMuller

输出结果:

muller@ubuntu:~/node$ node mymodule.js 
Node.js的文件系统的Api   AngelaMuller同步式读取
Node.js的文件系统的Api   AngelaMuller

异步读取文件与readFile相同,而读取到的文件内容会以函数返回值的形式返回,如果有错误发生,fs将抛出异常,你需要try和catch捕获并处理异常。
Node.js from fs.readFileSync() to fs.readFile()
其他方法请查看官方API https://nodejs.org/dist/latest-v4.x/docs/api/fs.html

三、 IO交互

什么是IO交互

简单点是Node.js的控制台输入输出,I 是input 可读输入流 ,O是output 可输出流,Node.js也有如同C++和Java的标准输入输出进行交互。

什么是Readline

Readline是Node.js里实现标准输入输出的封装好的模块,通过这个模块我们可以以逐行的方式读取数据流。
使用require("readline")可以引用模块。

如何使用Readline
// 引入readline模块
const readline = require('readline');

//创建readline接口实例
const rl = readline.createInterface({
    input: process.stdin,  //监听的可读流 (必填)
    output: process.stdout //逐行读取(Readline)数据要写入的可写流(可选)
});
rl.setPrompt('What is your name ? > ');//设置提示符
rl.prompt(); //为用户输入准备好逐行读取(Readline),让用户有新的地方输入


rl.on('line', function (str) {
    console.log('my name is : '+str);
});

// close事件监听
rl.on("close", function(){
   // 结束程序
   console.log('Have a great day!');
    process.exit(0);// 结束程序
});

/* v0.10.44 版本似乎有问题 v4.5.0案例
rl.on('line', (line) => {
    var str = line.trim();
    console.log('my name is : '+str);
    
    rl.prompt();
}).on('close', () => {
  console.log('Have a great day!');
  process.exit(0);
});
*/

在close事件的监听里,我们执行了process.exit(0)来使程序退出的操作,因为readline模块只要一开始获取用户输入就不会结束,必须使用这种直接的方式来结束程序。

输入与输出实例
// 引入readline模块
var readline = require('readline');

var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.on('line', function(line){
    switch(line.trim()) {
        case 'copy':
            console.log("复制");
            break;
        case 'hello':
            rl.write("Write");
            console.log('world!');
            break;
        case 'close':
            rl.close();
            break;
        default:
            console.log('没有找到命令!');
            break;
    }
});
rl.on('close', function() {
    console.log('bye bye');
    process.exit(0);
});

 'line'事件,这个事件就是在用户输完一行,按下回车后就会触发的事件,它会将用户输入的数据通过回调函数传回来,可在此方法里处理用户输入的数据

命令行输入与输出
const readline = require('readline');
const rl = readline.createInterface(process.stdin, process.stdout);

rl.setPrompt('OHAI> ');
rl.prompt();

rl.on('line', (line) => {
  switch(line.trim()) {
    case 'hello':
      console.log('world!');
      break;
    default:
      console.log('Say what? I might have heard `' + line.trim() + '`');
      break;
  }
  rl.prompt();
}).on('close', () => {
  console.log('Have a great day!');
  process.exit(0);
});

四、URL解析

1.URL模块为URL的解析工具
var url = require('url');
var urlString = 'http://user:pass@best.bluepay.asia:90/p/a/t/h?query=string#hash';
var result = url.parse(urlString);
console.log(result);

//第二个可选参数设置为true时  query: { query: 'string' },

输出结果:

muller@ubuntu:~/node$ node url.js
Url {
  protocol: 'http:',
  slashes: true,
  auth: 'user:pass',
  host: 'best.bluepay.asia:90',
  port: '90',
  hostname: 'best.bluepay.asia',
  hash: '#hash',
  search: '?query=string',
  query: 'query=string',
  pathname: '/p/a/t/h',
  path: '/p/a/t/h?query=string',
  href: 'http://user:pass@best.bluepay.asia:90/p/a/t/h?query=string#hash' }


2.queryString 模块

提供了实用程序来处理查询字符串

querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' })
// returns 'foo=bar&baz=qux&baz=quux&corge='

querystring.stringify({foo: 'bar', baz: 'qux'}, ';', ':')
// returns 'foo:bar;baz:qux'

// Suppose gbkEncodeURIComponent function already exists,
// it can encode string with `gbk` encoding
querystring.stringify({ w: '中文', foo: 'bar' }, null, null,
  { encodeURIComponent: gbkEncodeURIComponent })
// returns 'w=%D6%D0%CE%C4&foo=bar'
querystring.parse('foo=bar&baz=qux&baz=quux&corge')
// returns { foo: 'bar', baz: ['qux', 'quux'], corge: '' }

// Suppose gbkDecodeURIComponent function already exists,
// it can decode `gbk` encoding string
querystring.parse('w=%D6%D0%CE%C4&foo=bar', null, null,
  { decodeURIComponent: gbkDecodeURIComponent })
// returns { w: '中文', foo: 'bar' }
3. QueryString模块和Url模块之间的关系
  url.parse(string).query
                                           |
           url.parse(string).pathname      |
                       |                   |
                       |                   |
                     ------ -------------------
http://localhost:8888/start?foo=bar&hello=world
                                ---       -----
                                 |          |
                                 |          |
              querystring(string)["foo"]    |
                                            |
                         querystring(string)["hello"]

4. 获取静态资源

完整实例(根据不同的url地址请求不同的文件)

const ip = '192.168.1.223';//主机IP
const port = 3000;//端口号
//引入的组建模块  http、url、fs
const http = require('http');
const urls = require('url');
const fs = require('fs');
//实例化一个服务容器
var server = new http.Server();
//监听一个端口
server.listen(port , ip);
//注册一个事件处理的on方法
server.on('request' , function(req , res){
    //获取请求的url地址
    var url = urls.parse(req.url);
    //console.log(url.pathname);
    //根据path路径来读取不同的模板文件
    switch( url.pathname ){
        //显示首页
        case '' || '/':
            //读取文件内容
            fs.readFile('./index.html',function( error, content){
                if(error){
                    //如果有错误时,显示错误信息
                    funError();
                }else{
                    //正确时浏览器输出模板文件的内容
                    funAuccess(res,content);
                }
            });
            break;
        //显示列表页面
        case '/list':
            fs.readFile('./list.html',function( error, content){
                if(error){
                        funError(res , error);
                }else{
                    funAuccess(res,content);
                }
                });
            break;
        //显示详情页
        case '/show':
            fs.readFile('./show.html',function( error, content){
                if(error){
                    funError(res , error);
                }else{
                    funAuccess(res,content);
                }
            });
            break;
        //获取静态资源的页面 如:css\js
        default:
            //获取文件名
            var filename = url.pathname.substring(1);
            //获取文件名对应的类型值
            var type = getAllType( filename.substring(filename.lastIndexOf('.')+1));
            //测试所用
            //console.log(type);
            //读取静态资源的页面
            fs.readFile(filename , function( error, content){
                if(error){
                    funError(res , error);
                }else{
                    res.writeHead(200,{'Content-Type' : type});
                    res.write(content);
                    res.end();
                }
            });
            break;
    }

});
//错误提示的函数
function funError(response , error){
    response.writeHead(400,{'Content-Type':'text/plain;charset="utf-8"'});
    response.write(error.message);
    response.end();
}

//正确时输出文件内容的函数
function funAuccess(response,cont){
    response.writeHead(200,{'Content-Type':'text/html;charset="utf-8"'});//头信息
    response.write(cont);//模板文件内容
    response.end();
}


//定义文件类型的函数
function getAllType(code){
    var type = '';
    switch(code){
          case 'html':
            type = 'text/html;charset=utf-8';
            break;
        case 'js':
            type = 'application/javascript/html;charset=utf-8';
            break;
        case 'css':
            type = 'text/css;charset=utf-8';
            break;
            case 'text':
            type = 'text/plain;charset=utf-8';
            break;
        case 'manifest':
            type = 'text/cache-manifest;charset=utf-8';
            break;
        default:
            type = 'application/octet-stream';
            break;
    }
    return type;
}
上一篇下一篇

猜你喜欢

热点阅读