fs文件系统
文档地址:http://nodejs.cn/api/fs.html
fs模块提供了很多接口,用于操作系统文件。有一些是开发中经常用到的,总结一下方便查找这些API。
fs.rename
/**
* rename
* 文件重命名
*/
// 文件名不区分大小写
fs.rename(path.join(__dirname, './NOTE.md'), path.join(__dirname, './my.md'), (err) => {
if (err) throw err;
});
fs.watch
/**
* Watch
* 监控文件或文件夹的变化
*/
const filepath = path.join(__dirname, './static')
const watcher = fs.watch(filepath)
.on('change', (eventType, filename) => {
if (filename) {
console.log(eventType, filename);
}
})
.on('close', () => {
console.log('close')
})
// watcher.close() // 取消监控
fs.createReadStream
/**
* createReadStream
* 以流的方式加载文件,适用于小文件和大文件(如视频和音频)
*/
const filepath = path.join(__dirname, './static/111.jpg')
const stream = fs.createReadStream(filepath, {
highWaterMark: 1024, // 缓冲区大小,默认是 64kb, 这里设置为1kb
}).on('open', (fd) => {
console.log(fd) // 24 文件描述符: http://nodejs.cn/api/fs/file_descriptors.html
}).on('ready', () => {
console.log('ready', stream.path) // ready /Users/wmui/Documents/demo/node-demo/static/csp.html
}).on('data', () => {
console.log(stream.bytesRead) // 1024 2048 ... 如果文件很大,这里不是一次加载整个文件到内存中,而是分多次。
//stream.pause() 暂停读取和发射data事件
// stream.resume()恢复读取并触发data事件
}).on('end', () => {
console.log(stream.bytesRead) // 7428 最终的文件大小
}).on('error', () => {
}).on('close', () => {
console.log('close')
})
fs.stat
/**
* stats
* 读取文件或文件夹的相关信息
*/
const filepath = path.join(__dirname, './static')
fs.stat(filepath, (err, stats) => {
console.log(stats, stats.isDirectory(), stats.isFile())
})
// Stats {
// dev: 16777220,
// mode: 16877,
// nlink: 8,
// uid: 501,
// gid: 20,
// rdev: 0,
// blksize: 4194304,
// ino: 4727428,
// size: 256,
// blocks: 0,
// atimeMs: 1557904202743.3977,
// mtimeMs: 1557902949563.7786,
// ctimeMs: 1557902949563.7786,
// birthtimeMs: 1545472431878.8225,
// atime: 2019-05-15T07:10:02.743Z,
// mtime: 2019-05-15T06:49:09.564Z,
// ctime: 2019-05-15T06:49:09.564Z,
// birthtime: 2018-12-22T09:53:51.879Z
// }
// true false
fs.createWriteStream
/**
* createWriteStream
* 创建一个写入流
*/
const filepath = path.join(__dirname, './static/111.jpg')
const filepath2 = path.join(__dirname, './static/222.jpg')
const writeStream = fs.createWriteStream(filepath2, {
highWaterMark: 1024 // 默认是16K
})
fs.createReadStream(filepath).on('data', (data) => {
writeStream.write(data, 'utf8') // 如果文件未创建,一定要指定编码
})
fs.access
/**
* access
* 检测文件是否可操作
*/
const filepath = path.join(__dirname, './static/111.jpg')
// 检查当前目录中是否存在该文件。
fs.access(filepath, fs.constants.F_OK, (err) => {
console.log(`${err ? '不存在' : '存在'}`);
});
// 检查文件是否可读。
fs.access(filepath, fs.constants.R_OK, (err) => {
console.log(`${err ? '不可读' : '可读'}`);
});
// 检查文件是否可写。
fs.access(filepath, fs.constants.W_OK, (err) => {
console.log(`${err ? '不可写' : '可写'}`);
});
// 检查当前目录中是否存在该文件,以及该文件是否可写。
fs.access(file, fs.constants.F_OK | fs.constants.W_OK, (err) => {
if (err) {
console.error(
`${file} ${err.code === 'ENOENT' ? '不存在' : '只可读'}`);
} else {
console.log(`${file} 存在,且它是可写的`);
}
})
fs.appendFile
/**
* appendFile 追加数据
*/
const filepath = path.join(__dirname, './static/a.txt')
fs.appendFile(filepath, 'hello haha', 'utf8', (err) => {
if (err) throw err;
console.log('数据已追加到文件');
});
fs.realpath
/**
* realpath 不执行大小写转换,统一返回小写
* realpath.native 返回filepath对应的值
*/
const filepath = path.join(__dirname, './static/A.txt')
fs.realpath(filepath, (err, str) => {
console.log(str) // /Users/wmui/Documents/demo/node-demo/static/a.txt
})
fs.realpath.native(filepath, (err, str) => {
console.log(str) // /Users/wmui/Documents/demo/node-demo/static/A.txt
})
fs.writeFile
/**
* writeFile
* 向文件中写入数据,会清空原数据
*/
const filepath = path.join(__dirname, './static/a.txt')
const d1 = new Uint8Array(Buffer.from('hello'))
// 方式一:使用buffer,无需指定编码
fs.writeFile(filepath, d1, (err) => {
if (err) throw err;
})
// 方式二:字符串,必须指定编码
fs.writeFile(filepath, 'world', 'utf8', (err) => {
if (err) throw err;
})
fs.existsSync
/**
* existsSync
* 判断路径是否存在,可以是文件或者文件夹
*/
const filepath = path.join(__dirname, './static')
console.log(fs.existsSync(filepath)) // true
fs.unlink
/**
* unlink
* 删除文件。如果要删除文件夹,使用rmdir
*/
const filepath = path.join(__dirname, './static/222.jpg')
fs.unlink(filepath, (err) => {
if (err) throw err;
console.log('文件已删除');
})
fs.copyFile
/**
* copyFile
* 拷贝文件或文件夹,如果目标文件已存在,则覆盖
*/
const filepath = path.join(__dirname, './static/222.jpg')
const filepath2 = path.join(__dirname, './static/333.jpg')
// 拷贝222.jpg到333.jpg
fs.copyFile(filepath, filepath2, (err) => {
if (err) throw err
console.log('源文件已拷贝到目标文件')
})
// 拷贝222.jpg到333.jpg,如果已存在,则默认失败
const { COPYFILE_EXCL } = fs.constants
fs.copyFile(filepath, filepath2, COPYFILE_EXCL, (err) => {
if (err) throw err
console.log('源文件已拷贝到目标文件')
}) // Error: EEXIST: file already exists
fs.mkdir
/**
* mkdir
* 创建文件夹
*/
// 创建 /tmp/a/apple 目录,无论是否存在 /tmp 和 /tmp/a 目录。
fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
if (err) throw err;
});
fs.chmod
/**
* chmod
* 修改文件权限,可以是八进制值,也可以是fs.constants内置的常量
*/
const filepath = path.join(__dirname, './static/222.jpg')
fs.chmod(filepath, 0o777, (err) => {
if(err) throw err
})
fs.open
/**
* open
* 打开文件,操作结束后必须调用fs.close关闭文件,不然可能造成内存泄漏
*/
const filepath = path.join(__dirname, './static/a.txt')
fs.open(filepath, 'r', (err, fd) => {
if (err) throw err
fs.fstat(fd, (err, stat) => {
if (err) throw err
// 使用文件属性。
// 始终关闭文件描述符!
fs.close(fd, (err) => {
if (err) throw err
})
})
})
胖胖熊笔记,笔记已迁移