使用NodeJS进行文件传输

5hcedyr0  于 2023-10-17  发布在  Node.js
关注(0)|答案(1)|浏览(135)

我尝试使用JavaScript和NodeJS将一些文件从一个文件夹复制到另一个文件夹。我正在阅读文件名从一个文本文件,以实现这一点,但只有最后一个文件正在转移。FileNames.txt具有存在于F:/Some Folder/Origin Folder中的文件的名称,我想将这些文件复制到F:/Some Folder/Target Folder中。count变量用于验证传输的文件数量。

function readFileContents() {
  fs.readFile(
    "F:/Some Folder/FileNames.txt",
    "utf8",
    (err, data) => {
      if (err) {
        console.log(err);
      } else {
        data.split("\n").forEach(d => transferFiles(d));
      }
      console.log(count);
    }
  );
}

function transferFiles(fileName) {
  fs.cp(
    `F:/Some Folder/Origin Folder/${fileName}`,
    `F:/Some Folder/Target Folder/${fileName}`,
    err => {
      if (err) {
        console.log(err);
      } else {
        console.log(`Transferred ${fileName}`);
        count++;
      }
    }
  );
}
nxagd54h

nxagd54h1#

您的代码:

data.split("\n").forEach(d => transferFiles(d));

将开始所有的转移,并立即返回,而不等待任何一个被做。你展示的代码没有能力真正知道它们什么时候完成,也没有能力看到最终的计数是多少,因为你没有跟踪所有事情都完成的时间。
我建议使用await fs.promises.cp(...),这是该函数的承诺版本,然后您可以await每一个并按顺序执行它们,并且更容易知道它们何时完成。不要在异步代码中使用.forEach(),因为它不是promise感知的,不会尊重promise。相反,只使用普通的for循环或for/of循环,这两种循环都是promise和await友好的。
而且,当您使用它时,您也可以切换到const data = await fs.promises.readFile(...),这样您就可以始终使用promise来管理您的异步操作,而不是普通的回调。最好不要将promise与普通回调混合在一起。
下面是如何用promise对这些操作进行排序:

const fsp = fs.promises;

async function readFileContents() {
    const data = await fsp.readFile("F:/Some Folder/FileNames.txt", "utf8");
    const files = data.split("\n");
    let count = 0;
    for (let file of files) {
        await transferFile(file);
        ++count;
    }
    return count;
}

async function transferFiles(fileName) {
    try {
        await fsp.cp(
            `F:/Some Folder/Origin Folder/${fileName}`,
            `F:/Some Folder/Target Folder/${fileName}`
        );
        console.log(`Transferred ${fileName}`);
    } catch(err) {
        console.log(err);
        throw err;
    }        
}

readFileContents()的调用者将收到一个promise,该promise将解析为复制的文件数量的计数,否则将拒绝并返回一个错误。调用者可以在返回的promise上使用await.then()来获取计数。

相关问题