簡體   English   中英

使用Nodejs刪除目錄中的先前文件,創建新文件並下載新創建的文件

[英]Delete Previous Files in Directory, Create New Files and Download Newly Created Files With Nodejs

我正在創建一個簡單的節點應用程序。 我想要達到的目標:

我的應用程序將以網頁鏈接和一些關鍵字作為輸入。 現在我想根據輸入的關鍵字創建新的網頁。 因此,如果我進入優秀的程序員、優秀的問題解決者、nodejs 開發人員。 它應該創建 3 個新文件 good_programmer.php,great_problem_solver.php。 nodejs_developer.php 然后我想下載這些文件。

對於這個問題,我建議的解決方案如下:

    const fs = require("fs");
const path = require("path");
const axios = require("axios");
const cheerio = require("cheerio");
const zipadm = require("adm-zip");
const zip = new zipadm();
// initialize app
const app = express();
// to handle the forms
app.use(express.urlencoded({ extended: false }))
// initialize port
const PORT = 8000;
// util functions
function deletePreviousFiles() {
    return new Promise((res, rej) => {
        fs.readdir(__dirname, (err, files) => {
            if (err) throw err;
            for (const file of files) {
                if (file.includes(".php") || file.includes("sitemap.txt") || file.includes(".zip")) {
                    fs.unlink(path.join(__dirname, file), err => {
                        if (err) throw err;
                    });
                }
            }
            res();
        })
    })
}
function generateSitemapFile(webpage, words) {
    return new Promise((res, rej) => {
        let keywords = words.split(",");
        for (let i = 0; i < keywords.length; i++) {
            let fileName = keywords[i].trim().replace(" ", "_");
            let newLink = `${webpage}${fileName}.php`;
            fs.appendFile(`sitemap.txt`, `${newLink}\n`, function (err) {
                if (err) throw err;
            });
        }
        res();
    })
}
function generatePHPFiles(data, words) {
    return new Promise((res, rej) => {
        const $ = data;
        $.html();
        let keywords = words.split(",");
        for (let i = 0; i < keywords.length; i++) {
            let fileName = keywords[i].trim().replace(" ", "_");
            fs.writeFile(`${fileName}.php`, $.html(), (err) => {
                if (err) throw err;
            })
        }
        res();
    })
}
function createZipFile() {
    return new Promise((res, rej) => {
        fs.readdir(__dirname, (err, files) => {
            if (err) throw err;
            for (const file of files) {
                if (file.includes(".php") || file.includes("sitemap.txt")) {
                    zip.addFile(file);
                    data = zip.toBuffer();
                    zip.writeZip("NewPhpFiles.zip");
                }
            }
            res();
        })
    })
}
// controller
const startApplication = async (req, res, next) => {
    try {
        const webPageLink = req.body.link;
        const seoKeywords = req.body.keywords;        
        // delete previous files on desk
        await deletePreviousFiles();
        console.log("Previous Files Deleted...");
        // generate sitemap.txt file
        await generateSitemapFile(webPageLink, seoKeywords);
        console.log("Sitemap Created...");
        // get web page response
        let response = await axios.get(webPageLink);
        const data = await cheerio.load(response.data);
        console.log("Data Loaded From Page...")
        // create new php files
        generatePHPFiles(data, seoKeywords);
        console.log("PHP Files Created...")
        // create a zip file
        createZipFile();
        console.log("ZIP Created...")     
        next();
    } catch (error) {
        console.log(error)
    }
}
const downloadFile = async (req,res) => {
    try {
        setTimeout(()=>{
            res.download("NewPhpFiles.zip");
        },1000)
    } catch (error) {
        console.log(error)
    }
}
app.use(startApplication)
// initialize the route for application
app.post("/submit", downloadFile)
// start app
app.listen(PORT, console.log(`App is listening on port: ${PORT}...`)); 

所以,我正在刪除磁盤上現有的 php 文件,然后創建新文件並壓縮它們,但它不會下載新文件。 似乎創建新文件需要很多時間。

我認為你沒有完全理解 js 是如何工作的。 讓我們從那個開始。 例如,讓我們使用 deletePreviousFiles 函數。 fs.readdir 和 fs.unlink 有回調函數,你需要等待這些回調函數,以確保在函數執行時你想做的一切都完成了。 在 deletePreviousFiles 函數中,您正在等待 fs.readdir 而不是 fs.unlink。 也沒有正確處理錯誤。 有多種方法可以解決這個問題。 當然,您可以使用 callbaks 來完成,但有更簡單的解決方案。 您可以使用 fs 包提供的同步功能。 或者您可以使用 async/await 來避免回調混亂。 我強烈建議使用 fs/promise 包。

讓我們重構你的函數。

async function deletePreviousFiles() {
    let files = await fs.promises.readdir(__dirname);
    for (const file of files) {
        if (file.includes(".php") || file.includes("sitemap.txt") || file.includes(".zip")) {
            await fs.promises.unlink(path.join(__dirname, file))
        }
    }
}

通過這種方式,當您調用 deletePreviousFiles 函數時,您將確保您想做的一切都已完成。 (不要忘記這個函數是一個異步函數並返回一個承諾。所以你需要處理它。基本上用 await 調用)

在 downloadFile 函數中有一個超時函數。 我假設您這樣做是為了等待必要的操作。 這是錯誤的做法。 對於此類操作,您無法估計需要多長時間。 你需要確保它完成了。 不要使用超時來等待 io 操作!。

同樣在 startApplication 函數中,您使用 await 調用了一些異步函數,但您沒有調用其他一些函數。 例如,您在沒有等待的情況下調用了 generatePHPFiles。 因此,通過該行后,您將在控制台上打印文件已創建但實際上並未創建。

在其他一切之前,我認為您需要了解回調和 asyc/await 在 js 中是如何工作的。 如果您有更多問題,請隨時提出。 祝你有美好的一天 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM