I/O input / output
- 对外部设备的输入输出
- 外部设备
- 磁盘,网卡,显卡,打印机,其他...
- IO的速度往往低于内存和cpu的速度 《现代操作系统》-- 英文版
- 所以其中fs方法大部分是回调函数或者promise
fs -- 文件系统 模块常用的api
模块支持以标准 POSIX 函数建模的方式与文件系统进行交互
要使用基于 promise 的 API:import * as fs from 'fs/promises';
要使用回调和同步的 API:import * as fs from 'fs';
基本 都有 promise 和 回调的一异步 和同步方法 promise 示例
- 对同一文件执行多个并发修改时必须小心,否则可能会损坏数据
import { unlink } from 'fs/promises';
try {
await unlink('/tmp/hello');
console.log('successfully deleted /tmp/hello');
} catch (error) {
console.error('there was an error:', error.message);
}
回调函数 示例
- 当需要最大性能(在执行时间和内存分配方面)时,
fs模块 API 的基于回调的版本比使用 promise API 更可取。
import { unlink } from 'fs';
unlink('/tmp/hello',(error, content) => {
if(error) throw error
console.log(content) // content 一般会用十六进制表示
});
同步示例 会导致js运行阻塞(使用场景一般在 初始化时使用)
import { unlinkSync } from 'fs';
try {
unlinkSync('/tmp/hello');
console.log('successfully deleted /tmp/hello');
} catch (err) {
// 处理错误
}
- fs.readFile(
path[, options], callback) 异步读取文件全部内容
const fs = require("fs")
const path = require("path")
// 因为 node运行时会取当前所在文件的路径而不是运行文件路径,所以需要取绝对路径
const filename = path.resolve(__dirname,"./index.js")
fs.readFile(filename,(error,content) => {
if(error) throw error
console.log(conetent) // 获取的数据时buffer(实际是二进制) 打印出来十六进制的数字
// 可以用toString("utf-8")方法转为字符串
// h或者fs.readFile(filename,"utf-8",callback) 第二个参数传类型
})
- fsPromises.writeFile(file, data[, options])
- 异步地将数据写入文件,如果文件已经存在,则替换该文件
- 不想覆盖options 传对象{ flag: "a" // 追加内容 }
const fsPromise = require("fs/promises");
const path = require("path")
const filename = path.resolve(__dirname,"./a.js")
fs.readFile(filename,"utf-8",( error, content ) => {
console.log(content, filename)
})
async function writeString() {
// 如果目录找不到则会报错,文件找不到会添加该文件,后面加上options 参数会在文件后面添加,否则时覆盖
await fsPromise.writeFile(filename, "系统插入", { flag: "a" })
}
- fs.stat(
path[, options]) 获取文件状态内容
async function getStat() {
const stat = await fsPromise.stat(filename);
stat.isDirectory() // 判断是不是目录 返回Boolean
stat.isFile() // 判断是不是文件
console.log(stat);
}
// 打印
Stats {
dev: 1452664113,
mode: 16822,
nlink: 1,
uid: 0,
gid: 0,
rdev: 0,
blksize: 4096,
ino: 1688849860267985,
size: 0, // 占用字节数,如果是文件的size是有的,目录原因是里面只存指向文件的指针
blocks: 8,
atimeMs: 1648478262769.7976, // 上次访问的时间戳
mtimeMs: 1648477427945.434, // 上次修改的时间戳
ctimeMs: 1648477427945.434, // 上次修改文件状态的时间戳
birthtimeMs: 1646749596576.3237, // 文件创建的时间戳
atime: 2022-03-28T14:37:42.770Z,
mtime: 2022-03-28T14:23:47.945Z,
ctime: 2022-03-28T14:23:47.945Z,
birthtime: 2022-03-08T14:26:36.576Z
}
- fs.readdir(
path[, options], callback) 返回一个存放文件名的数组(不能嵌套)
async function getList() {
const list = await fsPromise.readdir(path.resolve(__dirname));
console.log(list);
}
- fs.mkdir(
path[, options]) 创建目录
async function createDir() {
await fsPromise.mkdir(path.resolve(__dirname, './first'));
}
- fs.access(path[, mode]) 判断文件权限
// 用stat的isDirectory() 和 isFile()
const stat = fs.statSync(path);
// stat.isDirectory() 为true的话那么存在,如果为false不存在
try{
stat.isFile() //走到这表示存在
}catch(e){
// 走到这表示不存在
}
// 检查当前目录中是否存在该文件。
access(file, constants.F_OK, (err) => {
console.log(`${file} ${err ? 'does not exist' : 'exists'}`);
});
// 检查文件是否可读。
access(file, constants.R_OK, (err) => {
console.log(`${file} ${err ? 'is not readable' : 'is readable'}`);
});
// 检查文件是否可写。
access(file, constants.W_OK, (err) => {
console.log(`${file} ${err ? 'is not writable' : 'is writable'}`);
});
// 检查文件是否可读可写。
access(file, constants.R_OK | constants.W_OK, (err) => {
console.log(`${file} ${err ? 'is not' : 'is'} readable and writable`);
});
- fs.unlink
(path, callback)删除文件 fs.rmdir(path[, options], callback)删除目录fs.rm(path[, options], callback)删除目录和文件