使用NodeJS压缩和解压缩文件

假设您有一个压缩文件目录,并且想全部解压缩。 可以通过单击全部将它们解压缩来手动实现,但是也可以使用简单的NodeJS脚本来实现。 前几天,我通过从AWS S3下载了数十个文件来做到这一点,令人惊讶的是,在网上找不到我想要的明确示例,所以我决定写这篇文章。

设定

如果要创建一些压缩文件进行练习,请按照以下说明创建新的Node项目并创建练习文件:

$ mkdir zipping-practice

$ cd zipping-practice

$ touch index.js

$ mkdir data

$ echo 'whatever text you want' > data/file1.txt (这将是您的练习文件之一,无论您想要多少,都可以)

$ gzip -r data/*.txt (这会压缩所有以.txt结尾的文件)

现在,您将看到数据中充满了以.gz结尾的文件,这是一种压缩格式。 压缩要通过HTTP发送的数据时,通常使用此格式。 您可以在这里阅读更多有关它的信息,但它很无聊💤

代码

在编辑器中打开index.js

我们将使用Node附带的名为Zlib的模块,该模块具有许多用于压缩和解压缩事物的方法。 我们还将使用文件系统模块允许我们从文件系统读取和写入数据(因为我们需要读取压缩文件并写入新的未压缩文件)。

首先,让我们先解压缩一个文件,然后再对所有文件进行解压缩:

我们引入所需的两个模块,然后使用readFileSync方法读取第一个文件,该方法比非阻塞的异步readFile方法更容易使用。

如果您现在记录fileContents您将看到类似以下内容:

  ReadStream { 
_可读状态:
ReadableState {
objectMode:否,
highWaterMark:65536,
缓冲区:BufferList {头:null,尾部:null,长度:0},
长度:0,
管道:null,
pipeCount:0,
流动:null,
结束:错误,
...等等

那看起来不像文件的内容! 什么是 那是压缩数据的样子吗?

不,这是一个“可读流”,它是一个对象(或接口),可让您读取二进制数据流。 这意味着什么? 这意味着该对象将为您一点一点地提供数据块(即文件的内容),因此您可以一点一点地处理文件,而不必将整个文件保存在内存中。 这对于大文件来说非常有用,但是除非您按照上述步骤将大量文本通过管道传输到文件中,否则我们将不需要将我们的文件以大块二进制数据的形式传递给我们。

不过太糟糕了,因为createReadStream将我们分块地( createReadStream给了我们,而我们对此无能为力。 😖而且请相信我,实际上并没有其他方法可以这样做,因为正如我们稍后将看到的那样,我们的解压缩方法要求我们使用流。

顺便说一句,如果您想了解更多信息,这是一篇很棒的关于流的文章

接下来,我们创建另一个流。 实际上两个。 一个writeStream (将允许我们将解压缩后的数据逐段地传送到一个文件中,而gunzip流将在为我们提供数据流后实际上为我们解压缩。

因此,我们通过管道传输文件内容,如下所示:

原始文件→解压缩流→新文件

如果打开file1.txt ,应该会看到它包含您之前输入的相同文本。

所有文件的所有解压缩

我们可以执行与上面相同的操作,但对于./data目录中的每个文件。 注意,将解压缩的文件写入新目录以保持分离是一个好主意。

请注意,当我们创建新文件的名称时,我们如何分割文件名的最终.gzfile1.txt.gz变为file1.txt

很好,但是如果您以后要以编程方式使用解压缩的文件,则需要知道解压缩过程何时完成。 由于使用writeStream写入文件系统是异步的,因此我们需要侦听一个事件,该事件告诉我们何时结束,并且还需要确保我们还有一种方法来了解何时解压缩所有文件。

通过映射文件名并为每个文件创建一个约定,我们可以安全地知道何时将所有文件解压缩。 当我们从writeStream接收到“ finish”事件时,我们将解决每个诺言,告诉它已完成对新文件的写入。

然后,您可以继续在下一个.then块continue中做任何您想做的事

再次将其全部压缩

好的,您改变了主意,想要再次压缩所有内容。

幸运的是,您只需要更改几个字符即可!

这样就可以用NodeJS进行压缩和解压缩。

谢谢阅读! 希望您学到了一些东西,并且别忘了跟我来阅读常规编程文章👋

X