You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中用WebDAV遍历Nextcloud文件夹下载文件生成空文件的问题

解决WebDAV循环下载文件内容为空的问题

咱们来拆解你遇到的问题,其实核心是两个小错误导致的:

1. 循环索引的低级失误

你在循环里一直硬写folder[0],不管循环迭代到第几次,都只会处理数组的第一个文件!这就导致后续生成的文件其实都是在重复覆盖第一个文件的空副本(因为流还没写完就被下一次迭代打断了)。

先把这个问题修正,把folder[0]改成folder[i],让循环真正遍历所有文件:

for (let i = 0; i < folder.length; i++) {
  const currentFile = folder[i]; // 拿到当前循环的文件对象
  // 后续用currentFile代替folder[0]
}

2. 未正确等待流操作完成

pipe()方法不会返回Promise,所以你写的await WebDav.createReadStream(...).pipe(...)根本起不到等待文件写入完成的作用。循环会立刻跳到下一次迭代,导致文件流还没来得及写入内容就被终止,最终生成0KB的空文件。

解决这个问题的关键是把流操作包装成Promise,通过监听流的finish和error事件来控制异步流程:

修正后的完整代码

const dir = "/foo";
const folder = await WebDav.getDirectoryContents("bar");

// 封装一个工具函数,把流操作转为Promise
const saveStreamToFile = (readStream, writeStream) => {
  return new Promise((resolve, reject) => {
    readStream.pipe(writeStream);
    // 监听写入完成事件
    writeStream.on("finish", resolve);
    // 监听读写过程中的错误
    writeStream.on("error", reject);
    readStream.on("error", reject);
  });
};

// 遍历文件并逐个下载
for (let i = 0; i < folder.length; i++) {
  const currentFile = folder[i];
  // 跳过子文件夹(如果有需要的话)
  if (currentFile.type === "directory") continue;
  
  const readStream = WebDav.createReadStream(currentFile.filename);
  const writeStream = fs.createWriteStream(`${dir}/${currentFile.basename}`);
  await saveStreamToFile(readStream, writeStream); // 等待当前文件写入完成再继续
}

额外小提示

如果你的目标文件夹里还有子文件夹,记得通过currentFile.type判断类型,避免尝试下载文件夹导致报错;如果想要提高下载效率,可以用Promise.all并发处理,但要注意控制并发数量,避免给服务器造成太大压力。

内容的提问来源于stack exchange,提问作者ShayanJZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 11:58:14