Javascript 在循环中写入文件并从临时目录中读取

Javascript 在循环中写入文件并从临时目录中读取,javascript,node.js,api,Javascript,Node.js,Api,我试图从API下载一个报告,但数据被发送回的方式是使用一个压缩文件夹,其中包含另一个文件夹,以及十几个压缩的JSON文件。为清楚起见,它看起来如下所示: report.zip/ ├── reportID/ <- this is a regular folder │ ├── reportID_123.json.gz │ ├── reportID_456.json.gz │ ├── reportID_789.json.gz │ └── reportID_159.json.gz

我试图从API下载一个报告,但数据被发送回的方式是使用一个压缩文件夹,其中包含另一个文件夹,以及十几个压缩的JSON文件。为清楚起见,它看起来如下所示:

report.zip/
├── reportID/ <- this is a regular folder
│   ├── reportID_123.json.gz
│   ├── reportID_456.json.gz
│   ├── reportID_789.json.gz
│   └── reportID_159.json.gz
最后一件事是,如果相关的话,当硬编码文件名而不是使用临时文件路径时,这一切似乎工作得更好(尽管仍然不完美)。不幸的是,我不得不使用临时文件路径,因为这是一个不允许常规路径的云函数

.pipe()
是异步的。所以,这一行代码:

inp.pipe(unzip).pipe(out);
inp.pipe(unzip).pipe(out);
在将来某个未知的时间结束。因此,您尝试使用以下命令读取输出文件:

fs.readFileSync(finalOutputName);
const allZips = zipEntries.map(zipeEntry => zipEntry.entryName);
在您知道输出已完成之前。如果要使用streams进行此操作,则需要注意writestream上的
close
事件,以便知道
.pipe()
已完成。您还应该注意流上的
错误
事件,以实现正确的错误处理

在为
close
事件实现了一个监听器来读取输出之后,按照您编写代码的方式,您必须等待所有流获得它们的
close
事件,然后才能使用
allData
,因为只有这样,它才会包含所有数据

在试图理解您的代码流程以提出替代方案时,我看到以下代码行:

inp.pipe(unzip).pipe(out);
inp.pipe(unzip).pipe(out);
但是,没有定义变量
unzip

此外,除了创建所有的临时文件之外,了解这段代码的最终目标是什么也会很有帮助,这样我们也许可以建议一种更好的方法


作为次要简化,您可以替换以下内容:

const allZips = [];
zipEntries.forEach(function(zipEntry) {
    allZips.push(zipEntry.entryName);
});
为此:

fs.readFileSync(finalOutputName);
const allZips = zipEntries.map(zipeEntry => zipEntry.entryName);


当我试图更好地理解这段代码时,您的两个流和
.pipe()
所要做的就是将提取的文件复制到一个新位置。使用或,您可以做得更简单。

inp.pipe(unzip.pipe)(out)
;解压是什么?for循环的
中的所有内容有什么意义。看起来您所做的只是将文件复制到一个没有扩展名
.gz
的新名称?这就是你想要做的吗?如果是这样,为什么不直接重命名文件呢?而且,您是否验证了
finalOutputName
确实是您想要的并且与任何内容都不冲突?您是否意识到,当您执行此
var zip=new AdmZip(tempFilePath)时,此代码所做的第一件事将使用将整个文件读取到内存中。首先,这是同步I/O,这对服务器环境非常不利。第二,它将整个文件读入内存,而您只想将其解压缩到磁盘上——除非您能保证这些文件总是小文件,否则在服务器环境中这是另一件不好的事情。@jfriend00否则我怎么做呢?我在谷歌上搜索了很久,似乎找不到任何方法在不先将文件读入内存的情况下提取zip文件的内容。有很多zip包,但它们都使用流,可以提取zip文件而无需将其读入内存。似乎您的代码应该做的只是将zip文件直接解压缩到最终位置,而不是将其解压缩到临时位置,然后将其复制到某个地方。这里有两个似乎符合要求的方案:和。