Outline

3 文件、进程、流和网络

  • 3.1 查询和读写文件
  • 3.2 创建和控制外部进程
  • 3.3 读写数据流

3 文件、进程、流和网络

3.1 查询和读写文件

path

从Node 0.8起,path模块只负责处理文件路径相关的字符串,不与实际文件或路径关联。

sample code:

/**
demonstration of module 'path' 's usage
*/
var path = require("path");

// 1 exists() - DEPRECATED use fs.exists("<path>", function(exists){}) instead
var fs = require("fs");
fs.exists("./path_demo.js", function(exists){// this file
  console.log(exists);
});
console.log(fs.existsSync("./path_demo.js"));// syn version

// 2 normalize()
console.log(path.normalize("/foo/bar/../baz"))

// 3 join()
var myPath = path.join("/foo", "bar", "..", "baz");
console.log(myPath);

// 4 resolve()
myPath = path.resolve("/hotdoc", "static_files/script", "../images/home.gif");
console.log(myPath);

// 5 relative()
myPath = path.relative("/data/test/aaa", "/data/src/aaa");
console.log(myPath);

// 6 dirname(), basename(), extname()
myPath = "/foo/bar/baz/index.html";
console.log("dirname="+path.dirname(myPath));
console.log("basename="+path.basename(myPath));
console.log("basename without extention="+path.basename(myPath, ".html"));
console.log("extname="+path.extname(myPath));

fs

fs模块用于查询文件的统计信息、文件的打开/读写/关闭等操作。

/**
demonstration of module 'fs''s usage,
files are put in $CWD/data
*/

var fs = require("fs");

// 1 stat()
fs.stat("./data/data.txt", function(error, stats){
  if(error){
    throw error;
  }
  console.log(stats);
  // hepler methods
  console.log("isFile="+stats.isFile());
  console.log("isDirectory="+stats.isDirectory());
  console.log("isBlockDevice="+stats.isBlockDevice());
  console.log("isCharacterDevice="+stats.isCharacterDevice());
  console.log("isSymbolicLink="+stats.isSymbolicLink());
  console.log("isFIFO="+stats.isFIFO());
  console.log("isSocket="+stats.isSocket());
});

// 2 open()
// 3 read()
fs.open("./data/data.txt", "r", function opened(error, fd){
  // fd: file descriptor
  if(error){ throw error; }

  var readBuffer = new Buffer(1024);
  fs.read(fd,
    readBuffer,
    0, // buffer's start position
    readBuffer.length,//data size
    0, // file postion
    function(error, readBytes){
      if(error) {throw error;}
      console.log("read "+ readBytes + " bytes");
      if(readBytes > 0){
        console.log(readBuffer.slice(0, readBytes).toString());
      }
    });

    fs.close(fd, function(){
      console.log("closed after read");
    });
});

// 4 write()
fs.open("./data/data.txt", "a", function(error, fd){// append mode
  if(error) {throw error;}

  var writeBuffer = new Buffer("this is the appended content");
  fs.write(fd,
    writeBuffer,
    0, // buffer's start position
    writeBuffer.length,// data size
    null, // current file's cursor
    function(error, writeBytes){
      if(error) {throw error;}
      console.log("write " + writeBytes + " bytes");
    }
  );

  fs.close(fd, function(){
    console.log("closed after write");
  });
});

// 5 close()
// default: file is closed when process end

3.2 创建和控制外部进程

(1) 执行外部进程

exec_external_cmd.js

/**
demonstration of execute external commands
*/

var exec = require("child_process").exec;
// execute "cat *.js | wc -l"
exec("cat *.js | wc -l", function(error, stdout, stderr){
  if(error){
    console.log("child process exited with error code: " + error.code);
    return;
  }
  console.log(stdout);//renderer the output of child process
});

// use configuration options
var options = {
  encoding: "utf8",
  timeout: 10000,
  killSignal: "SIGKILL",
  maxBuffer: 10 * 1024//default is 200*1024Bytes
};
exec("cat *.js | wc -c", options, function(error, stdout, stderr){
  if(error){
    console.log("child process exited with error code: " + error.code);
    return;
  }
  console.log(stdout);
});

// play with environment variables
// get this process's ENV
var env = process.env;
var envCopy = {};
for(var envVarname in env){
  envCopy[envVarname] = env[envVarname];// deep copy
}
envCopy["number"] = 123;// customed environment variable
exec("node child_env.js", {env: envCopy}, function(error, stdout, stderr){
  if(error) { throw error;}
  console.log("stdout:"+stdout);
  console.log("stderr:"+stderr);
});

child_env.js

/**
 a child process script to handle ENVs
*/
// ENV: number
var number = process.env.number;
console.log(typeof(number));// should be string

number = parseInt(number, 10);
console.log(typeof(number));

(2) 生成子进程

spawn_demo.js

/**
demonstration of spawn child processes
*/
var spawn = require("child_process").spawn;

// 1 spawn usage
// (1) not long-lived child process
// wc -l spawn_demo.js
//var child = spawn("wc", ["-l", "spawn_demo.js"]);

// (2) a long-lived child process
// tail -f spawn_demo.js
//var child = spawn("tail", ["-f", "spawn_demo.js"]);//this file

// (3) a sample IPC
/*
// node child_spawn.js
var child = spawn("node", ["child_spawn.js"]);
setInterval(function(){
  var number = Math.floor(Math.random() * 10000);

  // communicate to child process through FD stdin
  child.stdin.write(number+"\n");

  child.stdout.once("data", function(data){
    console.log("child's reply to " + number + " is " + data);
  });
}, 1000);
*/

// (4) child process killed by a singal
var child = spawn("sleep", ["5"]);

// 2 listen to child process's stdout
child.stdout.on("data", function(data){
  console.log("child output: "+ data);
});

child.stderr.on("data", function(data){
  console.log("child error output: " + data);
});

// listen to child process's exit
child.on("exit", function(code){
  console.log("child process exitd with code: " + code);
});

// listen to child process's exit with a returned signal
child.on("exit", function(code, signal){
  if(code){
    console.log("child process exitd with code: " + code);
  } else if(signal){
    console.log("child process killed by signal: " + signal);
  }
});

child_spawn_demo.js

/**
 demonstration of a spawnded child process to receive data from its stdin
*/

// unlock stream stdin's PAUSE state
process.stdin.resume();

process.stdin.on("data", function(data){
  var number;

  try{
    number = parseInt(data.toString(), 10);

    number += 1;

    // write to stdin
    process.stdout.write(number+"\n");
  } catch(error){
    process.stderr.write(err.message + "\n");
  }
});

(3) 进程间通信(IPC)

process_signal.js

/**
demonstration of sending signal to child process
*/
var spawn = require("child_process").spawn;

// [1]
//var child = spawn("sleep", ["10"]);

// [2]
var child = spawn("node", ["child_process_signal.js"]);

setTimeout(function(){
  // [1]
  // send a signal to child process: SIGTERM
  //child.kill();

  // [2]
  // send a signal to child process
  child.kill("SIGUSR2");
}, 3000);

// listeners
child.stdout.on("data", function(data){
  console.log("child stdout: " + data);
});

child.stderr.on("data", function(data){
  console.log("child stderr: " + data);
});

child.on("exit", function(code, signal){
  if(code){
    console.log("child process exitd with code: " + code);
  } else if(signal){
    console.log("child process killed by signal: " + signal);
  }
});

child_process_signal.js

/**
demonstration of process handle signals
*/
console.log("child process's pid="+process.pid);

var exec = require("child_process").exec;
exec("sleep 10", function(error, stdout, stderr){
  if(error){
    console.log("child process exited with error code: " + error.code);
    return;
  }
  console.log("stdout="+stdout);
  console.log("stderr="+stderr);
});

process.on("SIGUSR2", function(){
  console.log("incoming a SIGUSR2 singal, i will quit with killing myself");
  process.kill(process.pid);// kill self
});

3.3 读写数据流

文件流

可读read_stream.js

/**
demonstration of readable stream, including
events: data, end
method: pause(), resume()
*/
var fs = require("fs");

var options = {
  encoding: 'utf8',// null means will be Buffer in 'data' event, and  'utf8' means string
  fd: null, // an opened file descriptor
  bufferSize: 0,//size of file chunk
  start: 0, // start postion in file that want to read
  end:10 // end position in file that want to read
};
var readStream = fs.createReadStream("./data/data.txt", options);

readStream.on("data", function(data){
  console.log("type of data is : " + typeof(data));
  console.log(data.toString());
});

// pause the stream
readStream.pause();

// resume the paused stream
readStream.resume();

readStream.on("end", function(){
  console.log("the stream has ended");
})

可写write_stream.js

/**
demonstration of writeable stream, including
events: drain
method: write()
*/
var fs = require("fs");

var options = {
  flags: 'w',// same as fs.open()
  encoding: 'utf8',// same as readable buffer's options
  mode: 0666// file's priviledge
};
var writeStream = fs.createWriteStream("./data/data2.txt");

var inKernelOrQueue = writeStream.write("What is rational is real, and what is real is rational.");
// true means data has been sent to kernel's buffer,
// false means data had been save in queue in process's memory space
console.log("inKernelOrQueue="+inKernelOrQueue);

writeStream.on("drain", function(){
   console.log("data has been sent");
});

网络流

Socket是可读/可写流。
HTTP请求对象(request)是可读流,HTTP响应对象(response)是可写流。
具体内容见后面的模块说明。

慢客户端问题

典型场景:从可写流读,向可写流写入;但读的速度比写的速度快,需要可读流等待一下。

pipe_demo.js

/**
demonstration of readable stream's pipe() method,
it's used for handle write is more slow than read operation
*/
var http = require("http");
var fs = require("fs");

http.createServer(function(request, response){
  var readStream = fs.createReadStream("./data/data.txt");

  var options = {
    // true means the writeable stream's end() method will be called when the readable stream is end
    end: false
  };
  readStream.pipe(response, options);

  readStream.on("end", function(){
    response.write("that all the content");
    response.end();// directly call the end() method
  });

}).listen(8080);

Node.js高级编程读书笔记 - 2 文件和进程处理的更多相关文章

  1. Node.js高级编程读书笔记Outline

    Motivation 世俗一把,看看前端的JavaScript究竟能做什么. 顺便检验一下自己的学习能力. Audience 想看偏后台的Java程序员关于前端JavaScript的认识的职业前端工程 ...

  2. Node.js高级编程读书笔记 - 1 基本概念

    Outline 1 概述和安装 1.1 安装Node 1.2 Node简介 2 Node核心API基础 2.1 加载模块 2.2 应用缓冲区处理.编码和解码二进制数据 2.3 使用时间发射器模式简化事 ...

  3. Node.js高级编程读书笔记 - 6 应用程序构建和调试 - Never

    Explanation 现阶段console.log(...),util.inspect(...), JSON.stringify(...)在控制台输出已经够用了[2015/07/19]. 单元测试隶 ...

  4. Node.js高级编程读书笔记 - 4 构建Web应用程序

    Outline 5 构建Web应用程序 5.1 构建和使用HTTP中间件 5.2 用Express.js创建Web应用程序 5.3 使用Socket.IO创建通用的实时Web应用程序 5 构建Web应 ...

  5. Node.js高级编程读书笔记 - 3 网络编程

    Outline 3.4 构建TCP服务器 3.5 构建HTTP服务器 3.6 构建TCP客户端 3.7 创建HTTP请求 3.8 使用UDP 3.9 用TLS/SSL保证服务器的安全性 3.10 用H ...

  6. Node.js高级编程读书笔记 - 5 数据库 - Never

    Outline 6 连接数据库 6.1 使用node-mysql连接MySQL数据库 6.2 使用Nano连接CouchDB数据库 6.3 使用Mongoose连接MongoDB数据库 6 连接数据库 ...

  7. JS高级编程读书笔记

    导读:由于书的内容较多,内容划分也非常详尽,所以会分好几篇来写. 此页面仅作为跳转,权当个目录来用. 我会分块进行整理,大致如下: 第一章 简介 讲述javascript的历史,不打算整理,同学们大概 ...

  8. 《Node.js 高级编程》简介与第二章笔记

    <Node.js 高级编程> 作者简介 Pedro Teixerra 高产,开源项目程序员 Node 社区活跃成员,Node公司的创始人之一. 10岁开始编程,Visual Basic.C ...

  9. JavaScript、jQuery、HTML5、Node.js实例大全-读书笔记2

    技术很多,例子很多,只好慢慢学,慢慢实践!!现在学的这本书是[JavaScript实战----JavaScript.jQuery.HTML5.Node.js实例大全] JavaScript.jQuer ...

随机推荐

  1. Giving Data Backup Option in Oracle Forms 6i

    Suppose you want to give the data backup option in Oracle Forms application to some client users, wh ...

  2. JMeter进行简单的数据库(mysql)压力测试

    1.点击测试计划,再点击“浏览”,把JDBC驱动添加进来: 注:JDBC驱动一般的位置在java的安装地址下,路径类似于:    \java\jre\lib\ext 文件为:mysql-connect ...

  3. 从零开始HTML(一 2016/9/19)

    就是准备跟着W3C上的教程过一遍HTML啦,边看边记录更便于理解记忆吧~ 1.属性 HTML 标签可以拥有属性.属性提供了有关 HTML 元素的更多的信息.属性总是以名称/值对的形式出现,比如:nam ...

  4. nginx location配置

    nginx location配置   location在nginx中起着重要作用,对nginx接收到的请求字符串进行处理,如地址定向.数据缓存.应答控制.代理转发等location语法location ...

  5. laravel 加中间件的方法 防止直接打开后台

    路由 routes.php Route::group(['middleware' => ['web','admin.login.login']], function () { //后台首页路由 ...

  6. laravel Ajax post方式的使用

    以jquery ajax 的post的方式为例 验证邮箱输入格式是否正确 html <div class="fl"> <input type="emai ...

  7. OpenBSD为何还在用CVS之感

    一个轻松无聊的晚上突然想到一个问题——在当今这个Git大红大紫的时代,OpenBSD为何还在用CVS代码仓库?连他同阵营的FreeBSD都已经改用SVN,宣布逐渐废掉CVS了……问了下google,搜 ...

  8. 51nod 1135 原根

    题目链接:51nod 1135 原根 设 m 是正整数,a是整数,若a模m的阶等于φ(m),则称 a 为 模m的一个原根.(其中φ(m)表示m的欧拉函数) 阶:gcd(a,m)=1,使得成立的最小的 ...

  9. 20169212《Linux内核原理与分析》第一周作业

    实验 使用touch创建文件: man手册的内容很多,涉及了Linux使用过程中的方方面面,为了便于查找,是做了分册(分区段)处理的,在Research UNIX.BSD.OS X和Linux中,手册 ...

  10. spring随手笔记4:ref的属性

    1.local属性 引用在同一个xml的bean           只能引用bean的id <bean id="HelloWord" class="com.ltf ...