我如何获得可读文件?

How do I get a Readable File?

我有一个包含 99 个文件的目录,我想读取这些文件,然后将它们散列为 sha256 校验和。我最终想将它们输出到带有键值对的 JSON 文件,例如(文件 1、092180x0123)。目前我无法将我的 ParDo 函数传递给可读文件,我一定很容易遗漏一些东西。这是我第一次使用 Apache Beam,所以任何帮助都会很棒。这是我目前所拥有的

public class BeamPipeline {

    public static void main(String[] args)  {

        PipelineOptions options = PipelineOptionsFactory.create();
        Pipeline p = Pipeline.create(options);

            p
            .apply("Match Files", FileIO.match().filepattern("../testdata/input-*"))
            .apply("Read Files", FileIO.readMatches())
            .apply("Hash File",ParDo.of(new DoFn<FileIO.ReadableFile, KV<FileIO.ReadableFile, String>>() {
        @ProcessElement
        public void processElement(@Element FileIO.ReadableFile file, OutputReceiver<KV<FileIO.ReadableFile, String>> out) throws
        NoSuchAlgorithmException, IOException {
            // File -> Bytes
            String strfile = file.toString();
            byte[] byteFile = strfile.getBytes();


            // SHA-256
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] messageDigest = md.digest(byteFile);
            BigInteger no = new BigInteger(1, messageDigest);
            String hashtext = no.toString(16);
            while(hashtext.length() < 32) {
                hashtext = "0" + hashtext;
            }
            out.output(KV.of(file, hashtext));
        }
    }))
            .apply(FileIO.write());
        p.run();
    }
}

一个包含匹配文件名(来自 MetadataResult)和整个文件的相应 SHA-256(而不是逐行读取)的 KV 对的示例:

p
  .apply("Match Filenames", FileIO.match().filepattern(options.getInput()))
  .apply("Read Matches", FileIO.readMatches())
  .apply(MapElements.via(new SimpleFunction <ReadableFile, KV<String,String>>() {
      public KV<String,String> apply(ReadableFile f) {
            String temp = null;
            try{
                temp = f.readFullyAsUTF8String();
            }catch(IOException e){

            }

            String sha256hex = org.apache.commons.codec.digest.DigestUtils.sha256Hex(temp);   

            return KV.of(f.getMetadata().resourceId().toString(), sha256hex);
        }
      }
  ))
  .apply("Print results", ParDo.of(new DoFn<KV<String, String>, Void>() {
      @ProcessElement
      public void processElement(ProcessContext c) {
        Log.info(String.format("File: %s, SHA-256: %s ", c.element().getKey(), c.element().getValue()));
      }
    }
 ));

完整代码here。我的输出是:

Apr 21, 2019 10:02:21 PM com.dataflow.samples.DataflowSHA256 processElement
INFO: File: /home/.../data/file1, SHA-256: e27cf439835d04081d6cd21f90ce7b784c9ed0336d1aa90c70c8bb476cd41157 
Apr 21, 2019 10:02:21 PM com.dataflow.samples.DataflowSHA256 processElement
INFO: File: /home/.../data/file2, SHA-256: 72113bf9fc03be3d0117e6acee24e3d840fa96295474594ec8ecb7bbcb5ed024

我用在线哈希验证了tool:

顺便说一句,我认为您不需要 OutputReceiver 来获得单个输出(无侧输出)。感谢这些 questions/answers 的帮助:1, , 3.