上一節熟悉了常用的fs方法,現在就來練習一下文件的拷貝
一、小文件拷貝
代碼如下:
var fs=require('fs');
var filepath='./1.txt';
fs.stat(filepath,(error,stats)=>{
if(error){
console.log(error);
}else{
fs.readFile(filepath,(error,data)=>{
if(error){
console.log(error);
}else{
fs.writeFile('./copy.txt',data,(error)=>{
if(error){
console.log(error);
}else{
console.log('文件拷貝成功!');
console.log('文件內容如下:');
fs.readFile('./copy.txt','utf8',(error,data)=>{
if(error){
console.log(error);
}else{
console.log(data);
}
})
}
})
}
});
}
})
下面執行看下效果:
一開始文件夾里只有一個待拷貝的txt文件和一個js執行文件
拷貝前
文件執行后:
拷貝成功
可以看到成功拷貝生成了copy.txt文件,控制臺也輸出了文件內容
二、大文件拷貝
上邊的程序拷貝一些小文件沒啥問題,但這種一次性把所有文件內容都讀取到內存中后再一次性寫入磁盤的方式不適合拷貝大文件,內存會被撐爆。對于大文件,我們只能讀一點寫一點,直到完成拷貝,這個時候就用到了文件讀取流和寫入流。
- data事件
代碼如下:
var fs=require('fs');
var fileFrom='./sql_server.iso'; //待拷貝的文件路徑
var fileTo='./copy.iso' // 拷貝后的文件路徑
fs.stat(fileFrom,(error,stats)=>{
if(error){
console.log(error);
}else{
var fileSize=stats.size;
var totalChunk=0;
var reader=fs.createReadStream(fileFrom); //讀取流
var writer=fs.createWriteStream(fileTo); //寫入流
reader.on('data',(chunk)=>{
writer.write(chunk,(error)=>{
if(error){
console.log(error);
}else{
// 拷貝進度
totalChunk += chunk.length;
progress=parseInt((totalChunk/fileSize)*100)+'%'
console.log(progress);
}
})
})
reader.on('end',()=>{
console.log('文件拷貝完成');
})
}
})
這里增加了個顯示拷貝進度,準備文件是個2G多的大文件,如圖:
拷貝前
代碼執行過程中:
copy
Paste_Image.png
可以看到和期望中一樣,文件沒有問題
-
pipe
其實上面的代碼可以pipe進行簡化:
var fs=require('fs');
var fileFrom='./sql_server.iso'; //待拷貝的文件路徑
var fileTo='./copy.iso' // 拷貝后的文件路徑
fs.stat(fileFrom,(error,stats)=>{
if(error){
console.log(error);
}else{
var fileSize=stats.size;
var totalChunk=0;
var reader=fs.createReadStream(fileFrom); //讀取流
var writer=fs.createWriteStream(fileTo); //寫入流
//下面的這一段僅僅是為了顯示拷貝進度
writer.on('pipe',(read)=>{
//此處的read指向流向writer的讀取流,即reader===read
read.on('data',(chunk)=>{
// 拷貝進度
totalChunk += chunk.length;
progress=parseInt((totalChunk/fileSize)*100)+'%'
console.log(progress);
})
})
reader.pipe(writer); // 這一句話就可以實現文件的拷貝
}
})
實現拷貝的功能只需要這一句 reader.pipe(writer);
是不是最簡單了