读取、加密、压缩和发送文件,而无需重写文件

Read, encrypt, zip and send a file without rewriting it

提问人:ismala 提问时间:9/30/2023 更新时间:9/30/2023 访问量:56

问:

我有一个读取文件,压缩它,用 AES 算法加密它并将其发送到 S3 存储桶。

我实际代码的工作流程是:

  1. 读取文件并将其写入为 zip 文件(从Files.copy(filePath, zipOutputStream)java.nio.file
  2. 读取 zip 文件,加密并重写它

“伪代码”为 1。和 2.

    fileList.foreach(localFile => {
      zipOutputStream.putNextEntry(new ZipEntry(localFile.toPath.getFileName.toString))
      file.Files.copy(localFile.toPath, zipOutputStream)
      encryptAndReplace(localFile, someEncryptionConfig)
    })
  1. 读取加密的 zip 并将其发送到 s3(以FileInputStream S3OutputStreamWrapper)

我想在不重写文件的情况下完成所有这些步骤 2 次,并避免 IO 以节省时间。

我怎样才能优化我的工作流程?

如果我在步骤 1 中返回一个 InputStream。而不是重写它。然后在我的步骤 2 中重新返回一个 InputStream。然后将其发送到 S3,这是否意味着我的 2 个方法将返回整个文件? 我的整个文件将存储在内存中? 如果我以这种方式处理,我应该注意什么?

Java Scala IO InputStream 输出流

评论

1赞 rzwitserloot 9/30/2023
如果它都是 in- 和 outputstreams,它只是“流”(因此得名)。即使您处理了 GB 的数据,应用程序的内存占用量也会非常小(“流式处理”主要用于 zip 块结构需要几 MB,但它是一个常量值 - 处理两倍的数据,内存负载零变化),并且您也不需要任何磁盘空间。
0赞 ismala 9/30/2023
因此,如果我在加密文件后不写入文件,而是返回我的压缩函数将作为参数,则没有问题?InputStream
0赞 rzwitserloot 9/30/2023
是的,没关系。这就是它们的设计目的:)

答:

0赞 Rob Spoor 9/30/2023 #1

您无需读取和写入文件进行加密。使用您可以一口气完成所有事情。CipherOutputStream

Cipher cipher = ...;
try (OutputStream fileOut = Files.newOutputStream(...);
        CipherOutputStream cipherOut = new CipherOutputStream(fileOut, cipher);
        ZipOutputStream zipOut = new ZipOutputStream(cipherOut)) {

    // add entries to zipOut
}

我认为您甚至可以替换并一次性完成所有操作。fileOutS3OutputStreamWrapper