nodejs随记03

文件操作

  • 文件系统的操作
    * fs.readFile(filename, [options], callback)
    * fs.writeFile(filename, data, [options], callback)
//同步
  fs.writeFileSync('data/' + dist, fs.readFileSync(src));
//异步
  fs.readFile(src, function (err, data) {
    if (err) {
      throw err;
    } else {
      fs.writeFile(dist, data, function (err) {
        if (err) throw err; 
      })
    }
  });
  • 数据流操作
    • fs.createReadStream(path, [options]),
    • fs.createWriteStream(path, [options])
//使用pipe
  fs.createReadStream(src).pipe(fs.createWriteStream('./data/' + dist));
//
  var rs = fs.createReadStream(src);
  var ws = fs.createWriteStream(dist);
  rs.on('data', function (chunk) {
    if (ws.write(chunk) === false) {
      //判断写入还是缓存
      rs.pause();
    }
  });
  rs.on('end', function () {
    ws.end();
  });
  ws.on('drain', function () {
  	//已经写入的话继续
    rs.resume();
  });

fs内置模块常用api

  • 文件属性读写
    * fs.stat //获取文件信息
    * fs.chown //更改文件所有权
    * fs.chmod //改写文件的读写权限
  • 文件内容读写
    * fs.readFile
    * fs.readdir
    * fs,writeFile
    * fs.mkdir
  • 底层文件操作
    * fs.open
    * fs.read
    * fs.close
    * fs.unlink

读取文件

  • 使用fs.readStream读取文件;
var http = require('http');
var path = require('path');
var fs = require('fs');
var url = require('url');

var mimeTypes = {
  '.js' : 'text/javascript',
  '.html': 'text/html',
  '.css' : 'text/css'
};

//设置白名单
var whitelist = [
  '/index.html',
  '/style.css',
  '/script.js'
];

var cache = {
  store: {},
  maxSize : 26214400, //(bytes) 25mb
  maxAge: 5400 * 1000, //(ms) 1 and a half hours
  clearnAfter: 7200 * 1000,//(ms) two hours
  cleanedAt: 0, //to be set dynamically
  clean: function (now) {
    if (now - this.cleanAfter > this.cleanedAt) {
      this.cleanedAt = now;
      var maxAge = this.maxAge;
      Object.keys(this.store).forEach(function (file) {
        if (now > this.store[file].timestamp + maxAge) {
          delete this.store[file];
        }
      }.bind(this));
    }
  }
};


http.createServer(function (req, res) {
  if (req.url === '/favicon.ico') return;
  var lookup = url.parse(decodeURI(req.url)).pathname;
  lookup = path.normalize(lookup);
  lookup = (lookup === '/') ? '/index.html' : lookup;

  if (whitelist.indexOf(lookup) === -1) {
    res.writeHead(404);
    return res.end('Page Not Found!');
  }

  var f = './public' + lookup;
  console.log(f);
  fs.exists(f, function (exists) {
    if (exists) {
      var headers = {'Content-Type': mimeTypes[path.extname(lookup)]};
      if(cache.store[f]) {
        res.writeHead(200, headers);
        return res.end(cache.store[f].content);
      } 
      var s = fs.createReadStream(f).once('open', function () {
        res.writeHead(200, headers);
        this.pipe(res);
      }).once('err', function (err) {
        console.log('err:', e);
        res.writeHead(500);
        return res.end('Server Error!');
      });
      
      //对输出流保存cache处理;设置buffer需要大小,使用fs.stat获取
      return fs.stat(f, function (err, stats) {
        if (stats.size < cache.maxSize) {
          var bufferOffset = 0;
          cache.store[f] = {content: new Buffer(stats.size), timestamp: Date.now()};

          s.on('data', function (chunk) {
            chunk.copy(cache.store[f].content, bufferOffset);
            bufferOffset += chunk.length; //大小设置
          })
        }

      });
    }

    res.writeHead(404);
    return res.end('Not find Source!');
  });
  //清除超出时间的缓存
  cache.clean(Date.now());
}).listen(3000);

  • 使用fs.readFile读取文件
var http = require('http');
var path = require('path');
var fs = require('fs');

var mimeTypes = {
  '.js' : 'text/javascript',
  '.html': 'text/html',
  '.css' : 'text/css'
};
var cache = {};

function cacheAndDeliver (f, cb) {
  fs.stat(f, function (err, stats) {
    if (err) return console.log('Error: ',err);
    var lastChanged = Date.parse(stats.ctime);
    var isUpdated = cache[f] && lastChanged > cache[f].timestamp;
    if (!cache[f] || isUpdated) {
      fs.readFile(f, function (err, data) {
        if (!err) cache[f] = {content: data, timestamp: Date.now()}; //store a Unix time stamp
        cb(err, data);
      });
      return;
    }
    console.log('loading ' + f + ' from cache');
    return cb(null, cache[f].content);
  })
};

http.createServer(function (req, res) {
  if (req.url === '/favicon.ico') return;
  var lookup = path.basename(decodeURI(req.url)) || 'index.html';
  var f = './public/' + lookup;
  fs.exists(f, function (exists) {
    if (exists) {
      cacheAndDeliver(f, function (err, data) {
        if (err) {
          res.writeHead(500);
          res.end('Server Error!');
          return;
        }
        var headers = {'Content-Type': mimeTypes[path.extname(lookup)]};
        res.writeHead(200, headers);
        res.end(data);
      });
      return; //注意return的位置
    } 
    res.writeHead(404);
    return res.end('Not find Source!');
  })
}).listen(3000);

路径处理

  • url路径处理:
    * url.parse(req.url).pathname; url.parse(req.url, true).query

  • 文件路径处理:
    * path.join(__dirname, pathname);

path.dirname('/foo/bar/baz/asdf/quux')      '/foo/bar/baz/asdf'
//
path.basename('/foo/bar/baz/asdf/quux.html')    'quux.html'
path.basename('/foo/bar/baz/asdf/quux.html', '.html')     'quux'
//
path.extname('index.coffee.md')      '.md'
path.extname('index.')            '.'
path.extname('index')             ''
path.extname('.index')             ''
  • 递归一个文件夹例子
function travelS(dir, cb) {
  fs.readdirSync(dir).forEach(function (file) {
    var pathname = path.join(dir, file);
    if (fs.statSync(pathname).isDirectory()) {
      travelS (pathname, callback);
    } else {
      callback(pathname);
    }
  })
};

process

事件

  • process.on('exit', function(){});
  • process.on('uncaughtException', function(){});
  • 信号事件: :SIGINT,SIGUSR1...
    • 一个简单的方式发送SIGINT信号的方法是:control-c

方法

  • process.uptime(): Node的运行时间;
  • process.nextTick(func): 将函数放到后面运行;
  • process.cwd(): 显示当前文件夹目录;
  • process.exit(code): 退出进程,内部调用进程的exit事件,code:0表示成功退出,1表示失败退出;
  • process.kill(pid[, signal])#: 退出进程, 触发第二参数,为SIGINT,SIGHUP

属性

  • process.env: 运行环境参数;
  • process.stdin: 输入流;
    • process.stdin.resume();: 开启输入流,调用一次后程序不会马上停止;
    • process.stdin.setEncoding('utf8')
  • process.stdout: 输出流;
process.stdin.resume();
process.stdin.pipe(process.stdout);
  • process.stderr: 错误流;
  • process.pid: 进程的pid

数据交互

上传数据常用类型

  • application/x-www-form-urlencoded;
  • application/json;
  • application/xml;
  • multipart/form-data;

JSONP

//client
 var who = 'ryan';
  function cb(o) {
    alert(o.name + ' : ' + o.description);
  }
  var s = document.createElement('script');
  s.src = 'http://localhost:3000/?callback=cb&who=' + who;
  document.getElementsByTagName("head")[0].appendChild(s);

//server
  var profiles = require("./profiles.json");
  .....
  if(cb && who) {
    profile = cb + '(' + JSON.stringify(profiles[who]) + ')';
    return res.end(profile);
  }

上传文件例子

var http = require('http');
var formiable = require('formidable');
var fs = require('fs');

var form = require('fs').readFileSync('./public/form-upload.html');

http.createServer(function (req, res) {
  if (req.method === 'GET') {
    res.writeHead(200, {'Content-Type': 'text/html'});;
    return res.end(form);
  }

  if (req.method === 'POST') {
    var incoming = new formiable.IncomingForm();
    var f = './uploads';

    incoming.uploadDir = f;
    form.multiples = true;
    !fs.existsSync(f) && fs.mkdir(process.env.PWD + '/uploads'); //使用绝对路径创建文件夹

    incoming.on('fileBegin', function (field, file) {
      if(file.name) file.path += "-" + file.name;
    }).on('file', function (field, file) {
      if (file.size == 0) return fs.unlinkSync(file.path);
      res.write(file.name + ' received
');
    }).on('field', function (field, value) {
      res.write(field + ' : ' + value + '
');
    }).on('end', function () {
      res.end('All files received!');
    }).parse(req, function (err, fields, files) {

    });
  }

  if(req.method === 'PUT') {
    var f = './uploads';
    !fs.existsSync(f) && fs.mkdir(f);

    var fileData = new Buffer(+req.headers['content-length']);
    var bufferOffset = 0;

    req.on('data', function (chunk) {
      chunk.copy(fileData, bufferOffset); //连接Buffer对象的正确方法
      bufferOffset += chunk.length;
    }).on('end', function () {
      var rand = (Math.random()*Math.random()).toString(16).replace('.','');
      var to = 'uploads/' + rand + "-" + req.headers['x-uploadedfilename'];
      fs.writeFile(to, fileData, function (err) {
        if (err) throw err;
        console.log('Saved file to ' + to);
      })
    })
  }
}).listen(3000);

原文地址:https://www.cnblogs.com/jinkspeng/p/4860928.html