node基础篇之文件操作

写在前面

node中的文件操作算是非常频繁的了,它有非常多的api提供了对文件及文件夹的各种操作。下面通过对常见的api的案例讲解,来了解它们的具体用法。

一 读取文件 fs.readFile()、fs.readFileSync()

fs文件操作基本都包含同步和异步两种方式,后面都会同时对每种功能提供这两种方式的讲述,不在赘述。

异步 fs.readFile(文件名,[可选参数,编码方式,如’utf-8′],callback)

fs.readFile('/Users/kekobin/node-dir-test/util.js', (err, buffer) => {
    if(err) throw err;
    console.log(buffer.toString())
})   

callback回调包含err和buffer,默认不传编码方式,返回的是buffer二进制数据,不过可以通过

buffer.toString()

转为字符串。之所以默认使用buffer,是因为二进制流占用内存小,传输和运算快,性能高。

同步 fs.readFileSync(文件名,[可选参数,编码方式,如’utf-8′])

try {
    const buffer = fs.readFileSync('/Users/kekobin/node-dir-test/util.js')
} catch(e) {}

fs.readFile()、fs.readFileSync()在读取文件时,会不断的把读取的内容缓冲到内存中,直到缓冲完整个文件,所以对于大量或者大文件的读取时,一般使用fs.createReadStream() 进行流式传输替代,减少内存的压力。

二 写入文件 fs.writeFile() fs.writeFileSync()

异步 fs.writeFile(文件名,写入的内容,[可选参数,编码方式,如’utf-8′],callback)

fs.writeFile('/Users/kekobin/node-dir-test/util.js','test writing file', (err) => {
    if(err) { console.log('写入文件失败');return; }
    console.log('写入文件成功');
})   

callback回调只有err参数,表示写入是否成功。

同步 fs.writeFileSync(文件名,写入的内容,[可选参数,编码方式,如’utf-8′])

try {
    const err = fs.writeFileSync('/Users/kekobin/node-dir-test/util.js','test writing file')   
} catch(e) {}

三 创建文件夹 fs.mkdir() fs.mkdirSync()

异步 fs.mkdir(文件名,权限,callback)

fs.mkdir('/Users/kekobin/node-dir-test/test-dir',0777, (err) => {
    if(err) { console.log('创建文件夹失败');return; }
    console.log('创建文件夹成功');
})   

“权限”指的是被创建的文件夹是否可读、可写等。

同步 fs.mkdirSync(文件名,权限)

try {
    const err = fs.mkdirSync(''/Users/kekobin/node-dir-test/test-dir',0777)   
} catch(e) {}

四 获取文件或文件夹状态 fs.stat() fs.statSync()

往往通过这两个api判断正在处理的是文件,还是文件夹

异步 fs.stat(文件名或者文件夹名)

fs.stat('/Users/kekobin/node-dir-test/test-dir',(err, stats) => {
    if(err) throw err;
    if(stats.isFile()) {}
    if(stats.isDirectory()) {}
})   

回调中参数stats是一个包含文件或者文件夹信息的对象,最常用的是使用stats.isFile()判断是否文件,使用stats.isDirectory()判断是否文件夹。

同步 fs.statSync(文件名或者文件夹名)

try {
    const stats = fs.statSync('/Users/kekobin/node-dir-test/test-dir')   
} catch(e) {}

由于fs.exists()已经废弃了,所以判断文件或者文件夹是否存在,也可以通过这两个api判断,即读取一个文件夹,判断stats.isDirectory()是否为true,true说明存在,否则不存在。

五 读取目录 readdir(),readdirSync()

这两个api会返回一个所包含的文件和子目录的数组。

异步 fs.readdir(文件夹名)

const dir = '/Users/kekobin/node-dir-test/';
fs.readdir(dir, function (err, files) {
    if (err) {
      throw err;
      return;
    }

    files.forEach( (filename, index) => {
        const fullname = path.join(dir,filename);
        fs.stat(fullname, (err, stats) => {
            if(err) throw err;
            if(stats.isDirectory()) {

            }
            if(stats.isFile()) {
            }
        })
    });
});  

一般用于遍历文件夹,生成文件树等操作。

同步 fs.readdirSync(文件夹名)

try {
    const files = fs.readdirSync(dir)   
} catch(e) {}

六 创建文件读取流 fs.createReadStream(文件名)

往往用于打开大型的文本文件,创建一个读取操作的数据流。所谓大型文本文件,指的是文本文件的体积很大,读取操作的缓存装不下,只能分成几次发送,每次发送会触发一个data事件,发送结束会触发end事件。

let result = '';
fs.createReadStream('/Users/kekobin/node-dir-test/util.js')
.on('data', (data) => {
    result += data;
})
.on('end', () => {
    console.log('获取最终文件读取的内容', result);
})

七 创建文件写入流 fs.createWriteStream(文件名)

创建一个写入数据流对象,该对象的write方法用于写入数据,end方法用于结束写入操作。

const out = fs.createWriteStream(fileName, {
    encoding: 'utf8'
});
out.write(str);
out.end();

如createWriteStream和createReadStream配合实现拷贝大型文件。

function fileCopy(filename1, filename2, done) {
    var input = fs.createReadStream(filename1);
    var output = fs.createWriteStream(filename2);
  
    input.on('data', function(d) { output.write(d); });
    input.on('error', function(err) { throw err; });
    input.on('end', function() {
      output.end();
      if (done) done();
    });
}
// 将util.js拷贝到util2.js
fileCopy('/Users/kekobin/node-dir-test/util.js', '/Users/kekobin/node-dir-test/util2.js', function() {
    console.log('end')
})

八 删除文件 fs.unlink() fs.unlinkSync()

异步 fs.unlink(文件名)

fs.unlink('/Users/kekobin/node-dir-test/util2.js', function(err){
    if(err) throw err;
    console.log('文件删除成功');
}); 

同步 fs.unlinkSync(文件名)

try { fs.unlinkSync('/Users/kekobin/node-dir-test/util2.js') } catch(){}

九 删除目录 fs.rmdir() fs.rmdirSync()

异步 fs.rmdir(文件夹名,callback)

fs.rmdir('/Users/kekobin/node-dir-test/test-dir', function(err){
    if(err) throw err;
    console.log('目录删除成功');
}); 

同步 fs.rmdirSync(文件名)

try { fs.rmdirSync('/Users/kekobin/node-dir-test/test-dir') } catch(){}

实例:同步读取某个目录下所有文件

const getFiles = function(dir){
    const results = [];
    const files = fs.readdirSync(dir, 'utf8');

    files.forEach(function(file){
        const fullname = path.resolve(dir, file);
        const stats = fs.statSync(fullname);

        if(stats.isFile()){
            results.push(fullname);
        }else if(stats.isDirectory()){
            results = results.concat( getFiles(fullname) );
        }
    });

    return results;
};

const files = getFiles('/Users/kekobin/node-dir-test/');

本文收录在个人的Github上
https://github.com/kekobin/bl… ,觉得有帮助的,欢迎start哈。支持原创,未经本人同意,请勿转载!

    原文作者:kekobin
    原文地址: https://segmentfault.com/a/1190000019825908
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞