java - 使用 zip4j 损坏 NiFi ExecuteScript 输出

标签 java groovy stream apache-nifi zip4j

@Grab('net.lingala.zip4j:zip4j:2.2.8')
import net.lingala.zip4j.io.outputstream.ZipOutputStream;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.EncryptionMethod;

import org.apache.commons.io.IOUtils

flowFile = session.get()
if(!flowFile) return

flowFile = session.write(flowFile, {inputStream, outputStream ->
    byte[] inputByteArray = IOUtils.toByteArray(inputStream)

    ByteArrayOutputStream outputByteStream = new ByteArrayOutputStream()
    ZipOutputStream outputZipStream = new ZipOutputStream(outputByteStream, "password".toCharArray())

    //init the zip parameters
    ZipParameters zipParams = new ZipParameters()
    zipParams.setEncryptFiles(true)
    zipParams.setEncryptionMethod(EncryptionMethod.AES)
    zipParams.setFileNameInZip("records.csv")

    outputZipStream.putNextEntry(zipParams)
    outputZipStream.write(inputByteArray)
    outputZipStream.closeEntry()

    outputZipStream.close()
    outputByteStream.close()

    outputStream.write(outputByteStream.toByteArray())
} as StreamCallback)

session.transfer(flowFile, REL_SUCCESS)

我正在使用用 groovy 编写的执行脚本来压缩带有密码的 csv。执行脚本处理器能够毫无问题地将流文件传递到下一个处理器,但该文件已损坏。 PutSFTP 处理器提示以下错误。 enter image description here

尽管如此,该文件是通过 SFTP 存储的,但我无法解压缩它,因为它已损坏。我的代码有什么问题吗?

最佳答案

在开发自定义处理器来解压缩加密内容时,我们已成功使用以下代码片段使用 Lingala 解压缩受密码保护的流文件。请引用下面的代码将逻辑复制到 ExecuteScript 处理器 -

import net.lingala.zip4j.io.inputstream.ZipInputStream;
import net.lingala.zip4j.model.LocalFileHeader;

@Override
        public void unpack(final ProcessSession session, final FlowFile source, final List<FlowFile> unpacked) {
            final String fragmentId = UUID.randomUUID().toString();
            session.read(source, new InputStreamCallback() {
                @Override
                public void process(final InputStream in) throws IOException {
                    int fragmentCount = 0;

                    try (final ZipInputStream zipIn = new ZipInputStream(new BufferedInputStream(in), UNPACK_PASSWORD.toCharArray())) {
                        LocalFileHeader zipEntry;
                        while ((zipEntry = zipIn.getNextEntry()) != null) {
                            if (zipEntry.isDirectory() || !fileMatchesWithEncryption(zipEntry)) {
                                continue;
                            }
                            final File file = new File(zipEntry.getFileName());
                            final String parentDirectory = (file.getParent() == null) ? "/" : file.getParent();
                            final Path absPath = file.toPath().toAbsolutePath();
                            final String absPathString = absPath.getParent().toString() + "/";

                            FlowFile unpackedFile = session.create(source);
                            try {
                                final Map<String, String> attributes = new HashMap<>();
                                attributes.put(CoreAttributes.FILENAME.key(), file.getName());
                                attributes.put(CoreAttributes.PATH.key(), parentDirectory);
                                attributes.put(CoreAttributes.ABSOLUTE_PATH.key(), absPathString);
                                attributes.put(CoreAttributes.MIME_TYPE.key(), OCTET_STREAM);

                                attributes.put(FRAGMENT_ID, fragmentId);
                                attributes.put(FRAGMENT_INDEX, String.valueOf(++fragmentCount));

                                unpackedFile = session.putAllAttributes(unpackedFile, attributes);
                                unpackedFile = session.write(unpackedFile, new OutputStreamCallback() {
                                    @Override
                                    public void process(final OutputStream out) throws IOException {
                                        StreamUtils.copy(zipIn, out);
                                    }
                                });
                            } finally {
                                unpacked.add(unpackedFile);
                            }
                        }
                    }
                }
            });
        }

关于java - 使用 zip4j 损坏 NiFi ExecuteScript 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59539199/

相关文章:

java - 如何并行而不是顺序执行多个查询?

rest - Grails 2.4.3 : Consume a REST Service

gradle - 为什么Gradle不了解该文件是Groovy?

node.js - 从s3下载文件而不将其写入nodejs中的文件系统

java - Hibernate:搜索包含一组枚举中的值的实体

java - cucumber 数据表错误 - io.cucumber.datatable.UndefinedDataTableTypeException : Can't convert DataTable to cucumber. api.DataTable

c - 使用管道作为流 C

c# - 字节数组的缓冲流

java - 在 Java Spring 应用程序中找不到包

正则表达式转义 Groovy 中的特殊字符