{console.log(fd); // 3});fs.open("data.txt", "r", (err, fd) => {console.log(fd);fs.close(fd, (err) => {console.log('close successful');});}); 大文件读写操作 【。Node.js文件、目录操作实例。" />

Node.js文件、目录操作实例

文件打开和关闭

fs.open(path.resolve("data.txt"), "r", (err, fd) => { console.log(fd); // 3 }); fs.open("data.txt", "r", (err, fd) => { console.log(fd); fs.close(fd, (err) => { console.log('close successful'); }); });

大文件读写操作
【Node.js文件、目录操作实例】涉及open和write两个方法
// read 读操作就是将数据从磁盘文件写入到buffer中 // read(fd: number, --定位当前被打开的文件 // buffer: Buffer, --用于标识当前缓冲区 // offset: number, --从buffer哪个位置开始写操作 // length: number, --当前次写入的字节长度 // position: fs.ReadPosition, --从磁盘文件中哪一个字节开始读取 // callback: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void let buf = Buffer.alloc(10); fs.open("data.txt", "r", (err, readfd) => { console.log(readfd); fs.read(readfd, buf, 1, 3, 2, (err, readBytes, data) => { console.log(readBytes); console.log(data); console.log(data.toString()); }); }); // write(fd: number,--定位当前被打开的文件 //buffer: Buffer, --用于标识当前缓冲区 //offset: number, --从buffer哪个位置开始读取数据 //length: number,--当前次写的字节长度 //position: number, --从哪个字节开始写操作 //callback: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void let buf = Buffer.from('1234567890') fs.open('a.txt','w',(err,writefd)=>{ fs.write(writefd,buf,1,3,0,(err,written,buffer)=>{ console.log(written)// 3 console.log(buffer)// console.log(buffer.toString()) // 1234567890 fs.close(writefd) }) })

文件拷贝自定义实现
/** * 1打开a文件,利用read将数据保存到buffer暂存起来 -- a文件内容为1234567890 * 2,打开b文件,利用write将buffer中数据写入到b文件 */ let buf = Buffer.alloc(10); // 打开指定文件 fs.open("a.txt", "r", (err, readfd) => { // 打开b文件,用于执行数据写入操作 fs.open("b.txt", "w", (err, writefd) => { // 从打开的文件读取数据 fs.read(readfd, buf, 0, 10, 0, (err, readBytes) => { // buffer写入到b.txt中 fs.write(writefd, buf, 0, 10, 0, (err, wirtten) => { console.log("write successful"); }); }); }); });

针对大文件边读边写,利用buffer缓冲区完成操作
let buf = Buffer.alloc(10); const BUFFER_SIZE = buf.length; let readOffset = 0; fs.open("a.txt", "r", (err, readfd) => { fs.open("b.txt", "w", (err, writefd) => { function next() { fs.read(readfd, buf, 0, BUFFER_SIZE, readOffset, (err, readBytes) => { if (!readBytes) { // 如果条件成立,内容已经读取完毕 fs.close(readfd, () => {}); fs.close(writefd, () => {}); console.log("拷贝完成"); return; } readOffset += readBytes; fs.write(writefd, buf, 0, readBytes, (err, written) => { next(); // 递归读写 }); }); } next(); }); });

FS目录操作API access 判断文件或目录是否具有操作权限
stat 获取目录及文件信息
mkdir 创建目录
rmdir 删除目录
readdir 读取目录中的内容
unlink 删除指定文件
fs.access("a.txt", (err) => { if (err) { console.log(err); } else { console.log("有操作权限"); } }); fs.stat("a.txt", (err, statObj) => { console.log(statObj.size); // 14 console.log(statObj.isFile()); // true console.log(statObj.isDirectory()); // false }); fs.mkdir("a/b/c", (err) => { if (!err) { console.log("create successful"); } else { console.log(err); // 此时报错,要保证a/b存在才能创建c } }); fs.mkdir("a/b/c", { recursive: true }, (err) => {// 递归创建,不用保证a/b目录存在 if (!err) { console.log("create successful"); } else { console.log(err); // 此时报错,要保证a/b存在才能创建c } }); fs.rmdir("a/b/c", (err) => {// a/b/c都存在的情况下,只会删除c . 默认情况下只能删除非空目录 if (!err) { console.log("delete successful"); } else { console.log(err); } }); fs.rmdir("a", { recursive: true }, (err) => { // 递归删除 if (!err) { console.log("delete successful"); } else { console.log(err); } }); fs.readdir("a", (err, files) => { console.log(files); // [ 'a.txt', 'b' ]默认只会查看第一层,结果是个数组 }); fs.unlink("a/a.txt", (err) => { if (!err) { console.log("del successful"); } });

目录创建同步实现
/** * 1将来调用时需要接收类似于a/b/c,这样的路径,他们之间才欧用 / 进行连接 * 2利用 / 分割符将路径进行拆分,将每一项放入一个数组中进行管理 ['a' , 'b', 'c'] * 3对上述数组进行遍历,我们需要拿到每一项,然后与前一项进行拼接 * 4判断一下当前拼接之后的路径是否具有可操作性的权限,如果有则证明存在,否则就需要执行创建 */ function makeDirSync(dirPath) { let items = dirPath.split(path.sep); console.log(items); // [ 'a', 'b', 'c' ] for (let i = 1; i <= items.length; i++) { // 这里从下标1开始 let dir = items.slice(0, i).join(path.sep); console.log(dir); try { fs.accessSync(dir); } catch (err) { fs.mkdirSync(dir); } } }makeDirSync("a\\b\\c");

目录创建异步实现
function mkDir(dirPath, cb) { let parts = dirPath.split("/"); let index = 1; function next() { if (index > parts.length) { return cb && cb(); } let current = parts.slice(0, index++).join("/"); fs.access(current, (err) => { if (err) { // 没有操作权限 fs.mkdir(current, next); } else { next(); } }); } next(); }mkDir("a/b/c", () => { console.log("create successful"); });

利用es6 方法实现,需要使用util包里面的promiseify
const { promisify } = require("util"); // 将access与mkdir处理传给你async风格 const access = promisify(fs.access); const mkdir = promisify(fs.mkdir); async function myMkdir(dirPath, cb) { let parts = dirPath.split("/"); for (let index = 1; index <= parts.length; index++) { let current = parts.slice(0, index).join("/"); try { await access(current); } catch (error) { await mkdir(current); } } cb && cb(); }myMkdir("a/b/c", () => { console.log("create successful"); });

目录删除之异步实现
/** * 需求:子弟你一个函数,接收一个路径,然后执行删除操作 * 1,判断当前传入的路径是否为一个文件,直接执行删除当前文件 * 2,如果当前传入的是一个目录,我们需要继续读取目录中的的内容,然后再执行删除操作 * 3,将删除行为定义成为一个函数,然后通过递归的方式进行复用 * 4,将当前的名称拼接成在删除时可以使用的路径 */function myRmDir(dirpath, cb) { // 判断当前dirpath类型 fs.stat(dirpath, (err, statObj) => { if (statObj.isDirectory()) { // 目录,继续读取 fs.readdir(dirpath, (err, files) => { let dirs = files.map((item) => path.join(dirpath, item)); console.log(dirs); let index = 0; function next() { if (index === dirs.length) { return fs.rmdir(dirpath, cb); // 遍历完成,删除最外层目录 } let current = dirs[index++]; myRmDir(current, next); } next(); }); } else { // 文件--直接删除 fs.unlink(dirpath, cb); } }); }myRmDir("a.txt", () => { // 文件 console.log("del successful"); }); myRmDir("a", () => { // 目录 console.log("del successful"); });

    推荐阅读