node基础篇之文件操作

32次阅读

共计 4181 个字符,预计需要花费 11 分钟才能阅读完成。

写在前面

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 哈。支持原创,未经本人同意,请勿转载!

正文完
 0