通过4中不通的方式实现对一个文件的拷贝
方式一:readFile 异步一次性读取文件再写入
//异步形式读取文件 function copyFile(url){const extName = path.extname(url)const fileName = path.basename(url)const dirName = path.dirname(url)fs.readFile(url, (err, data) => {fs.writeFile(`${dirName}/${fileName}_copy_1${extName}`, data , err => {if(err){console.log(`写入出现错误 ${err.toString()}`)}else{console.log('完成!')}})}) }
方式二:readFileSync 同步一次性读取文件再写入
//同步形式读取文件 function copySync(url){const extName = path.extname(url)const fileName = path.basename(url)const dirName = path.dirname(url)var data = fs.readFileSync(url) fs.writeFileSync(`${dirName}/${fileName}_copy_1${extName}`,data)console.log('同步拷贝完成!') }
方式三:使用流边读边写
const fs = require('fs') const path = require('path')// 使用流拷贝 function streamCopyFile(url){const extName = path.extname(url)const fileName = path.basename(url)const dirName = path.dirname(url)let options = {highWaterMark : 64 * 1024 //默认值,每个chunk的大小 }const readable = fs.createReadStream(url, options)const writable = fs.createWriteStream(`${dirName}/${fileName}_copy${extName}`)var size = 0var totalSize = 0const stat = fs.stat(url, (err , stats) => {totalSize = stats.size})readable.on('open', () => {console.log('打开文件');})readable.on('data', data => {size = data.length + sizeconsole.log('已完成 ' + parseInt((size / totalSize) * 100) + '%');writable.write(data)readable.pause()})readable.on('end', () => {console.log('读取完成')})readable.on('error', err => {console.log(`读取时出现错误 ${err.toString()}`)})writable.on('error', err => {console.log(`写入时出现错误 ${err.toString()}`)})//将内存中数据全部写入文件后触发 drain 事件writable.on('drain', () => {readable.resume()})writable.on('finish', () => {console.error('写入完成');}) }
方式四:使用pipe
//通过管道的方式 function pipeCopyFile(url){const extName = path.extname(url)const fileName = path.basename(url)const dirName = path.dirname(url)const readable = fs.createReadStream(url)const writable = fs.createWriteStream(`${dirName}/${fileName}_copy_2${extName}`)var size = 0var totalSize = 0const stat = fs.stat(url, (err , stats) => {totalSize = stats.size})writable.on('pipe', (src) => {console.log('有数据正通过管道流入写入器')})writable.on('finish', () => {console.error('写入已完成')})readable.pipe(writable) }
方法一和方法二使用起来简单,但是在操作大文件时对内存压力大,不推荐读取大文件使用
另外如果需要对文件制定块进行读取和写入请使用read 、write 两个方法