PutFile附加文件

时间:2016-05-30 16:24:07

标签: apache-nifi

Nifi的新手!

我想知道在nifi中是否有办法使用诸如“PutFile”之类的处理器并将其写入一个文件(将数据附加到此文件,或覆盖此文件中的数据) - 而是比创建多个不同的文件?我需要使用另一个处理器才能完成此任务吗?

5 个答案:

答案 0 :(得分:3)

目前无法将数据附加到文件,但您可以使用PutFile覆盖该文件。

PutFile处理器使用FlowFile上的属性“filename”将文件写入磁盘。因此,如果您将一个UpdateAttribute处理器放在PutFile之前,该处理器将所有传入的FlowFile更新为相同的“文件名”,那么PutFile处理器将在磁盘上以相同的文件名将它们全部写入。

要使用PutFile执行此操作,请确保将处理器属性“冲突解决策略”配置为“替换”。

答案 1 :(得分:2)

对不起。新的。让我再试一次......

LogAttribute处理器可能是一个选项,因为它似乎提供了与文件追加最接近的功能。但它似乎并不理想,因为它提供了很少的指导输出的选项。

如果您打算使用"开箱即用,可以尝试另外两种选择"处理器功能而不是开发类来定制。使用ExecuteScript处理器执行Jython,Groovy或JS脚本,该脚本修改输出flowFile以仅包含所需的属性。使用PutMongo或PutSQL处理器来更新持久数据库资源。

如果您没有可供使用的数据库资源,请使用另一个选项:使用上面提到的ExecuteScript处理器,然后使用PutFile将一个唯一命名的filename属性输出到目录 - 比如$ {filename}。$ {} UUID。您将获得大量类似格式的文件 - 每个文件一个日志记录 - 然后您可以使用Linux行命令将其汇总到一个文件中进行分析,或者在工作流程中使用最终的ExecuteScript处理器进行汇总每次通过工作流程处理文件时。最后一个可能不是一个好主意,因为如果您的flowFiles流很高,它是否会引入同步和写入争用问题尚不清楚。

答案 2 :(得分:1)

适用于那些不想覆盖文件中数据但想要附加数据的人

使用ExecuteStreamCommand处理器附加到单个文件

putFile处理器无法实现,但是您可以使用ExecuteStreamCommand处理器来完成此操作。

在命令参数中,将要记录的属性以定界符分隔 ${aatr1};${aatr2};${attr3}

在命令路径中放入bash脚本的绝对路径:/path/logger.sh

logger.sh

#!/bin/bash
echo "$1|$2|$3">> /path/attributes.log

attibutres.log将逐行追加三个属性。确保bash脚本可通过nifi执行。

做一个chmod 777 logger.sh

使用ExecuteScript Processor附加到单个文件

尝试使用此ECMAscript:

var flowFile = session.get();
var File = Java.type("java.io.RandomAccessFile");
if (flowFile != null) {
    var filename = flowFile.getAttribute("filename");
    /// write to file
    var filePath = "/path/attributes.log" ;
    flowFile = session.putAttribute(flowFile, "filePath", filePath);
     var file = new File(filePath, "rws");
     file.seek(file.length());
        file.write(filename.getBytes());
        file.write("\n".getBytes());
        file.close();
    // Finish by transferring the FlowFile to an output relationship
    session.transfer(flowFile, REL_SUCCESS);
}

答案 3 :(得分:0)

有一种或多种将数据附加到文件的解决方案。我更喜欢使用ExecuteGroovyScript处理器进行文件追加。您可以通过groovy脚本轻松获取文件。那么如果文件存在,我们可以追加数据。我成功实现了此方法。

答案 4 :(得分:0)

最初的问题是附加到现有文件。大概的想法是为每个流文件写一行。

您可以使用不同的方法实现此用例:不是将连续的行附加到文件中,而是在 Nifi 中进行合并,然后一次性写出整个文件。这是通过 MergeContent 处理器完成的。它获取连续流文件的内容,并将它们粘贴到单个流文件中。它有各种配置选项来说明在输出合并结果之前要累积多少个流文件,然后您可以使用 PutFile 写出。

这是一个以 CSV 格式将关键属性写出到硬编码位置的方法。这对于在清空队列之前存档队列很有用。

假设您要写出属性 idnamesize

  • 添加处理器 AttributesToCSV。将“属性列表”设置为 id,name,size
  • 将“目的地”设置为“流文件内容”。
  • 将其下游连接到 MergeContent。
  • 设置“最小/最大条目数”,以便您的整个队列适合一个垃圾箱(例如,分别为 1 和一些大数字)
  • 将“分隔符策略”设置为“文本”
  • 将“Demarcator”设置为换行符(输入+,或粘贴到换行符中)
  • 在“Header”中设置适当的 CSV 标题,例如"ID,Name,Size" 并添加一个尾随换行符
  • 将“Max bin age”设置为几秒 - 足够长以有时间合并所有内容,但足够短以让您乐于等待。
  • 将其下游连接到将 filename 属性设置为您喜欢的任何内容的 UpdateAttribute
  • 将该下游连接到 PutFile,设置“目录”属性

其他一切都可以保持默认。

这个配方需要适应其他情况:

  • 如果有需要写出的恒定流:按条目数拆分成bins,并使文件名动态
  • 如果需要 CSV 以外的其他格式:将 AttributesToCSV 替换为其他处理器