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
相关产品推荐
相关产品推荐

