node基本模块使用
模块分类
- 自定义模块
- 系统核心模块
- fs 文件操作
- http 网络操作
- path 路径操作
- querystring 查询参数解析
- url url解析
- …
1.导出和导入
在NodeJS中,每个js文件就是一个模块,而文件路径就是模块名, 在编写每个模块时,都有require、exports、module三个预先定义好的变量可供使用。
require函数用于在当前模块中加载和使用别的模块,其中js扩展名可省略,require多次不会重复初始化,如果传递给require函数的是NodeJS内置模块名称,不做路径解析,require(‘express’);
exports对象是当前模块的导出对象,用于导出模块公有方法和属性。别的模块通过require函数使用当前模块时得到的就是当前模块的exports对象。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9h4v0DOA-1584629969149)(img/模块.png)]
导入导出结合使用:
var sum = function (a,b) {
return parseInt(a) + parseInt(b);
}
// 导出模块
// exports.sum = sum;
// module导出成员的方式 导出的是单独的方法
module.exports = sum;
/* 引入模块 */
var module = require("./01");
/* var ret = module.sum(2, 3);
console.log(ret) */
var ret = module(7, 8);
console.log(ret);
__filename获取当前模块文件的带有完整绝对路径的文件名。
__dirname获得当前文件所在目录的完整目录名
2、path模块
路径操作
- 路径基本操作API
path
模块提供用于处理文件路径和目录路径的实用工具。 它可以使用以下方式访问:
const path = require('path');
- path.basename(path[, ext])
path.basename(path[, ext])
path < string >
ext < string > 可选的文件扩展名。 加上的话会把扩展名去掉,只留下文件名
返回: < string >
path.basename() 方法返回 path 的最后一部分, 类似于 Unix 的 basename 命令。 尾部的目录分隔符将被忽略。
// 获取路径的最后一部分(最后的文件名 + 扩展名)
path.basename(path[, ext])
console.log(path.basename('/foo/bar/baz/asdf/quux.html')); // quux.html
console.log(path.basename('/foo/bar/baz/asdf/quux.html', '.html')); // quux
- path.dirname(path)
path
: < string >
返回: < string >
path.dirname()
方法返回 path
的目录名,类似于 Unix 的 dirname
命令。 尾部的目录分隔符将被忽略.
path.dirname('/foo/bar/baz/asdf/quux.txt');
// 返回: '/foo/bar/baz/asdf'
- path.extname(path)
path < string >
返回: < string >
path.extname() 方法返回 path 的扩展名, 从最后一次出现.(句点) 字符到 path 最后一部分的字符 串结束。 如果在 path 的最后一部分中没有.,或者如果 path 的基本名称( 参阅 path.basename()) 除了第一个字符以外没有.,则返回空字符串。
path.extname('index.html');
// 返回: '.html'
path.extname('index.coffee.md');
// 返回: '.md'
path.extname('index.');
// 返回: '.'
path.extname('index');
// 返回: ''
path.extname('.index');
// 返回: ''
path.extname('.index.md');
// 返回: '.md'
- path.format(pathObject)
pathObject < Object >
dir < string >
root < string >
base < string >
name < string >
ext < string >
返回: < string >
path.format() 方法从对象返回路径字符串。 与 path.parse() 相反。
当为 pathObject 提供属性时, 注意以下组合, 其中一些属性优先于另一些属性:
如果提供了 pathObject.dir, 则忽略 pathObject.root。
如果 pathObject.base 存在, 则忽略 pathObject.ext 和 pathObject.name。
- path.parse(path)
路径的格式化处理
// path.format() obj -> string
// path.parse() string->obj
let obj = path.parse(__filename);
console.log(obj);
/*
{
root: '/', 文件的根路径
dir: '/Users/liqi/Desktop/jiyun/nodejs/未命名文件夹/03-node基础', 文件的全路径
base: '02.js', 文件的名称
ext: '.js', 扩展名
name: '02' 文件的名称
}
*/
let objpath = {
root: "/",
dir: "/Users/aaa/bbb/ccc",
base: "abc.txt",
ext: ".txt",
name: "abc"
}
let strpath = path.format(objpath);
console.log(strpath); // /Users/aaa/bbb/ccc/abc.txt
- path.isAbsolute(path)
path < string >
返回: < boolean >
path.isAbsolute() 方法检测 path 是否为绝对路径。
如果给定的 path 是零长度字符串, 则返回 false。
// 在 POSIX 上:
path.isAbsolute('/foo/bar'); // true
path.isAbsolute('/baz/..'); // true
path.isAbsolute('qux/'); // false
path.isAbsolute('.'); // false
// 在 Windows 上
path.isAbsolute('//server'); // true
path.isAbsolute('\\\\server'); // true
path.isAbsolute('C:/foo/..'); // true
path.isAbsolute('C:\\foo\\..'); // true
path.isAbsolute('bar\\baz'); // false
path.isAbsolute('bar/baz'); // false
path.isAbsolute('.'); // false
- path.join([…paths])
…paths < string > 路径片段的序列。
返回: < string >
path.join() 方法使用平台特定的分隔符作为定界符将所有给定的 path 片段连接在一起, 然后规范化生成的路径。
零长度的 path 片段会被忽略。 如果连接的路径字符串是零长度的字符串, 则返回 ‘.’,
表示当前工作目录。
// 拼接路径 (..表示上层路径; .表示当前路径),在连接路径的时候会规范化路径
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
// 返回: '/foo/bar/baz/asdf'
- path.normalize(path)
path < string >
返回: < string >
path.normalize() 方法规范化给定的 path, 解析 ‘…’ 和 '.'片段。
当找到多个连续的路径段分隔字符时( 例如 POSIX 上的 / 、Windows 上的\ 或 / ),则它们将被替换为单个平台特定的路径段分隔符( POSIX 上的 / 、Windows 上的\)。 尾部的分隔符会保留。
如果 path 是零长度的字符串, 则返回 ‘.’,表示当前工作目录
// 在 POSIX 上:
path.normalize('/foo/bar//baz/asdf/quux/..');
// 返回: '/foo/bar/baz/asdf'
// 在 Windows 上:
path.normalize('C:\\temp\\\\foo\\bar\\..\\');
// 返回: 'C:\\temp\\foo\\'
//由于 Windows 识别多种路径分隔符,因此这些分隔符都将被替换为 Windows 首选的分隔符(\):
path.win32.normalize('C:temp\\\\/\\/\\/foo/bar');
// 返回: 'C:\\temp\\foo\\bar'
- path.posix
- path.relative(from, to)
from < string >
to < string >
返回: < string >
path.relative() 方法根据当前工作目录返回 from 到 to 的相对路径。 如果 from 和 to 各自解析到相同的路径( 分别调用 path.resolve() 之后), 则返回零长度的字符串。
如果将零长度的字符串传入 from 或 to, 则使用当前工作目录代替该零长度的字符串。
// 计算相对路径
// 在 POSIX 上:
path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb');
// 返回: '../../impl/bbb'
// 在 Windows 上:
path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb');
// 返回: '..\\..\\impl\\bbb'
- path.resolve([…paths])
…paths < string > 路径或路径片段的序列。
返回: < string >
path.resolve() 方法将路径或路径片段的序列解析为绝对路径。
给定的路径序列从右到左进行处理, 每个后续的 path 前置, 直到构造出一个绝对路径。 例如, 给定的路径片段序列: / foo、 / bar、 baz, 调用 path.resolve(’/foo’, ‘/bar’, ‘baz’) 将返回 / bar / baz。
如果在处理完所有给定的 path 片段之后还未生成绝对路径, 则再加上当前工作目录。
生成的路径已规范化, 并且除非将路径解析为根目录, 否则将删除尾部斜杠。
零长度的 path 片段会被忽略。
如果没有传入 path 片段, 则 path.resolve() 将返回当前工作目录的绝对路径。
// 解析路径
path.resolve('/foo/bar', './baz');
// 返回: '/foo/bar/baz'
path.resolve('/foo/bar', '/tmp/file/');
// 返回: '/tmp/file'
path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
// 如果当前工作目录是 /home/myself/node,
// 则返回 '/home/myself/node/wwwroot/static_files/gif/image.gif'
- path.sep
< string >
提供平台特定的路径片段分隔符:
Windows 上是\。
POSIX 上是 /
console.log(path.delimiter); // 表示变量分隔符 (windows 中使用; Linux中使用:)
console.log(path.sep); // / 表示路径分隔符(windows 是 \ ; Linux 是 /)
- path.delimiter
< string >
提供平台特定的路径定界符:
- 用于 POSIX
- path.toNamespacedPath(path)
- path.win32
3、fs模块
文件操作
带sync的都是同步的方法,不带sync的都是异步的方法
- 文件信息获取
dirent.isDirectory()
返回: < boolean >
如果 fs.Dirent 对象描述文件系统目录, 则返回 true。
dirent.isFile()
返回: < boolean >
如果 fs.Dirent 对象描述常规文件, 则返回 true。
fs.stat (path[, options], callback
) 返回文件的信息
// 引入fs 文件系统
const fs = require('fs');
fs.stat("./data.txt", function (err, stat) {
// 一般回调函数的第一个参数是错误对象,如果err为null,表示没有错误,否则表示报错了
if (err) return;
if (stat.isFile()) {
console.log("文件")
} else if (stat.isDirectory) {
console.log("目录")
}
console.log(stat);
/*
atime 访问时间 (access )
ctime 修改时间( change 文件的状态发生变化的时候, 权限)
mtime 文件数据发生变化的时间(modified 当文件的数据被修改的时候)
birthtime 创建时间
*/
})
- 读文件操作
const fs = require("fs");
const path = require("path");
let strpath = path.join(__dirname, "data.txt");
/* fs.readFile(strpath, (err, data) => {
if (err) return;
console.log(data); // <Buffer 31 39 30 39 41> 1909A
console.log(data.toString()); // 1909A
}) */
// 如果有第二个参数并且是编码,n那么回调函数获取到的数据就是字符串
// 如果没有第二个参数,那么得到的就是Buffer实例对象
fs.readFile(strpath,"utf8", (err, data) => {
if (err) return;
console.log(data); // 1909A
})
// 同步操作
let ret = fs.readFileSync(strpath, "utf8");
console.log(ret);
- 写文件操作
/*
写文件操作
fs.writeFile(file, data[, options], callback)
fs.writeFileSync(file, data[, options])
*/
const fs = require("fs");
const path = require("path");
let strpath = path.join(__dirname, "data.txt");
// 异步写入文件
/*
// 写入字符串
fs.writeFile(strpath, "hello nihao", (err) => {
console.log(err);
if(!err){
console.log("文件写入成功")
}
})
*/
/*
// 写入buffer
let buf = Buffer.from("hi");
fs.writeFile(strpath, buf, (err) => {
if (!err) {
console.log("文件写入成功")
}
})
*/
// 同步写入文件
fs.writeFileSync(strpath, "tom and jerry");
- 大文件操作
// =========================================================
/*
大文件操作(流式操作)
*/
// fs.createReadStream(path[, options])
// fs.createWriteStream(path[, options])
const path = require("path");
const fs = require("fs");
let spath = path.join(__dirname, "file.zip");
let dpath = path.join("/Users/liqi/Desktop", "file.zip");
// 读取文件的数据流
let readStream = fs.createReadStream(spath);
// 写文件的数据流
let writeStream = fs.createWriteStream(dpath);
// 基于事件的处理方式 事件驱动程序 data事件
// chunk 是一块数据 每读取一块数据就调用一下data
/*
let num = 1;
readStream.on("data", (chunk) => {
num++;
writeStream.write(chunk);
})
// 什么时候读取完呢 end事件
readStream.on("end", () => {
console.log("文件处理完成" + num);
}) */
// --------------------------------------------
// 另外一种语法 pipe 管道 读取流和写入流连接到一块 读的数据直接传给写的入口
readStream.pipe(writeStream);
- 目录操作
/*
目录操作
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");
// 创建目录 异步的方式
// 第一个参数是创建目录的路径 对应的回调函数就一个参数 err 错误回调
/*
fs.mkdir(path.join(__dirname, "abc"), (err) => {
console.log(err)
});
*/
// 创建目录 同步方式
// fs.mkdirSync(path.join(__dirname, "hello"));
// ---------------------------------------------------
// 读取目录 异步
/*
fs.readdir(__dirname, (err, files) => {
console.log(files); // [ '01.js','02.js','03.js','04.js','05.js','06.js','07.js','08.js','abc','data.txt','file.zip','hello']
files.forEach((item, index) => {
fs.stat(path.join(__dirname, item), (err, stat) => {
if (stat.isFile()) {
console.log(item,"文件")
} else if (stat.isDirectory()) {
console.log(item,"目录")
}
})
})
})
*/
// 读取目录 同步
let files = fs.readdirSync(__dirname);
files.forEach((item, index) => {
fs.stat(path.join(__dirname, 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);
// })
// 删除目录 同步
fs.rmdirSync(path.join(__dirname,"hello"));