Rumah >hujung hadapan web >tutorial js >Kaedah operasi fail tempatan Node.js salinan fail dan direktori traversal_node.js
Salinan fail
NodeJS menyediakan API operasi fail asas, tetapi fungsi lanjutan seperti penyalinan fail tidak disediakan, jadi mari berlatih dengan program penyalinan fail terlebih dahulu. Sama seperti arahan salin, program kami perlu boleh menerima dua parameter: laluan fail sumber dan laluan fail sasaran.
Salinan fail kecil
Kami menggunakan modul fs terbina dalam NodeJS untuk melaksanakan program ini seperti berikut.
var fs = require('fs'); function copy(src, dst) { fs.writeFileSync(dst, fs.readFileSync(src)); } function main(argv) { copy(argv[0], argv[1]); } main(process.argv.slice(2));
Atur cara di atas menggunakan fs.readFileSync untuk membaca kandungan fail daripada laluan sumber dan menggunakan fs.writeFileSync untuk menulis kandungan fail ke laluan sasaran.
Pengetahuan kacang: proses ialah pembolehubah global dan parameter baris arahan boleh diperoleh melalui process.argv. Memandangkan argv[0] adalah tetap sama dengan laluan mutlak program boleh laku NodeJS, dan argv[1] adalah tetap sama dengan laluan mutlak modul utama, parameter baris arahan pertama bermula dari kedudukan argv[2].
Salinan fail besar
Atur cara di atas tidak mempunyai masalah untuk menyalin beberapa fail kecil, tetapi kaedah membaca semua kandungan fail ke dalam memori pada satu masa dan kemudian menulisnya ke cakera sekali gus tidak sesuai untuk menyalin fail besar, dan memori akan menjadi letih. Untuk fail yang besar, kita hanya boleh membaca sedikit dan menulis sedikit sahaja sehingga salinan selesai. Oleh itu, program di atas perlu diubahsuai seperti berikut.
var fs = require('fs'); function copy(src, dst) { fs.createReadStream(src).pipe(fs.createWriteStream(dst)); } function main(argv) { copy(argv[0], argv[1]); } main(process.argv.slice(2));
Atur cara di atas menggunakan fs.createReadStream untuk mencipta strim data baca sahaja untuk fail sumber dan menggunakan fs.createWriteStream untuk mencipta strim data tulis sahaja untuk fail sasaran dan menggunakan kaedah paip untuk menyambungkan kedua-dua aliran data. Apa yang berlaku selepas sambungan dibuat, untuk meletakkannya secara lebih abstrak, ialah air mengalir dari satu baldi ke baldi yang lain di sepanjang paip.
Lintas direktori
Merentasi direktori ialah keperluan biasa apabila memanipulasi fail. Sebagai contoh, apabila menulis program yang perlu mencari dan memproses semua fail JS dalam direktori tertentu, ia perlu melintasi keseluruhan direktori.
Algoritma Rekursif
Algoritma rekursif biasanya digunakan semasa merentasi direktori, jika tidak, sukar untuk menulis kod ringkas. Algoritma rekursif adalah serupa dengan aruhan matematik kerana ia menyelesaikan masalah dengan mengurangkan saiznya secara berterusan. Contoh berikut menggambarkan pendekatan ini.
function factorial(n) { if (n === 1) { return 1; } else { return n * factorial(n - 1); } }
Fungsi di atas digunakan untuk mengira faktorial N (N!). Seperti yang anda lihat, apabila N lebih besar daripada 1, masalahnya berkurangan kepada pengiraan faktorial N darab N-1. Apabila N sama dengan 1, masalah mencapai saiz minimumnya dan tiada pemudahan selanjutnya diperlukan, jadi 1 dikembalikan secara langsung.
Perangkap: Walaupun kod yang ditulis menggunakan algoritma rekursif adalah ringkas, memandangkan setiap rekursif menjana panggilan fungsi, apabila prestasi perlu diutamakan, algoritma rekursif perlu ditukar kepada algoritma gelung untuk mengurangkan bilangan panggilan fungsi.
Algoritma Traversal
Direktori ialah struktur pokok, dan algoritma traversal yang didahulukan dengan mendalam + prapesan biasanya digunakan semasa melintasi. Kedalaman terlebih dahulu bermakna selepas mencapai nod, melintasi nod anak dahulu dan bukannya nod jiran. Preorder traversal bermakna traversal selesai apabila nod dicapai buat kali pertama, bukannya kali terakhir ia kembali ke nod. Oleh itu, apabila menggunakan kaedah traversal ini, susunan traversal di bawah ialah A > B >
A / \ B C / \ \ D E F
Perjalanan segerak
Setelah memahami algoritma yang diperlukan, kami hanya boleh melaksanakan fungsi traversal direktori berikut.
function travel(dir, callback) { fs.readdirSync(dir).forEach(function (file) { var pathname = path.join(dir, file); if (fs.statSync(pathname).isDirectory()) { travel(pathname, callback); } else { callback(pathname); } }); }
Seperti yang anda lihat, fungsi ini menggunakan direktori sebagai titik permulaan untuk traversal. Apabila subdirektori ditemui, subdirektori itu dilalui terlebih dahulu. Apabila fail ditemui, laluan mutlak ke fail dihantar ke fungsi panggil balik. Selepas fungsi panggil balik mendapat laluan fail, ia boleh membuat pelbagai pertimbangan dan proses. Jadi katakan kita mempunyai direktori berikut:
- /home/user/ - foo/ x.js - bar/ y.js z.css
Apabila merentasi direktori menggunakan kod berikut, input yang diperoleh adalah seperti berikut.
travel('/home/user', function (pathname) { console.log(pathname); });
/home/user/foo/x.js /home/user/bar/y.js /home/user/z.css
Perjalanan tak segerak
Jika API tak segerak digunakan untuk membaca direktori atau membaca status fail, fungsi traversal direktori akan menjadi sedikit rumit untuk dilaksanakan, tetapi prinsipnya adalah sama. Versi tak segerak bagi fungsi perjalanan adalah seperti berikut.
function travel(dir, callback, finish) { fs.readdir(dir, function (err, files) { (function next(i) { if (i < files.length) { var pathname = path.join(dir, files[i]); fs.stat(pathname, function (err, stats) { if (stats.isDirectory()) { travel(pathname, callback, function () { next(i + 1); }); } else { callback(pathname, function () { next(i + 1); }); } }); } else { finish && finish(); } }(0)); }); }
Teknik untuk menulis fungsi lintasan tak segerak tidak akan diperkenalkan secara terperinci di sini. Ini akan diperkenalkan secara terperinci dalam bab seterusnya. Ringkasnya, kita dapat melihat bahawa pengaturcaraan tak segerak agak rumit.