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

/**
* 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
       })
   })
})
posted @ 2021-10-08 10:15  wmui  阅读(136)  评论(0编辑  收藏  举报