java - 将 ByteArrayOutputStream 发送到 Perl 脚本,然后读取响应

标签 java perl stream outputstream

我有一个通过执行 diff 收到的 ByteArrayOuputStream。 Java 对此的解析太慢了,所以我决定尝试将解析传递给 Perl 脚本。我在让脚本从该输出流接收数据时遇到了一些麻烦。当我运行代码时,应用程序无限期挂起。这是我到目前为止所拥有的:

public static Diff analyzeDiff(ByteArrayOutputStream baos) throws IOException {

    ProcessBuilder pb = new ProcessBuilder();
    pb.command("perl/path/perl", TEMP.getAbsolutePath());
    Process process = pb.start();
    OutputStream str = process.getOutputStream();
    baos.writeTo(str);
    str.flush();
    try {
        process.waitFor();
    } catch (InterruptedException e) {
        BufferedReader bf = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line = bf.readLine()) != null) {
            System.out.println(line);
        }
    }

    return null;
}

@Test
public void testDiffParser() throws IOException {
    DiffParser.init();

    File test = new File("path/to/file/test.diff");

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    baos.write(FileUtils.readFileToByteArray(test));
    //String output = baos.toString();
    //System.out.println(output);

    DiffParser.analyzeDiff(baos);
    //DiffParser.analyzeDiff(output);
}

这是我的 Perl 脚本:

#!/usr/bin/perl
use strict;
use warnings;

my $additions = 0;
my $deletions = 0;
my $filesChanged = 0;

my $fileAdded = 0;
my $line;

foreach $line ( <> ) {
    $_ = $line;
    chomp( $_ );
    print( $_ );
    if ( /^\-\-\-/m ) {
        $fileAdded = 1;
    } elsif ( /^\+\+\+/m && $fileAdded ) {
        $filesChanged++;
        $fileAdded = 0;
    } elsif ( /^\+/ ) {
        $additions++;
        $fileAdded = 0;
    } elsif ( /^\-/ ) {
        $deletions++;
        $fileAdded = 0;
    } else {
        $fileAdded = 0;
    }
}

print("$additions $deletions $filesChanged\n")

有没有办法真正做我想做的事情?

编辑:这就是我在 Java 中的做法:

private Diff parseDiff(final ByteArrayOutputStream baos) {

    final Diff diff = new Diff();

    int filesChanged = 0;
    int additions = 0;
    int deletions = 0;

    boolean fileAdded = false;

    final String[] lines = baos.toString().split("\n");

    for (final String line : lines) {

        if (line.startsWith("---")) {
            fileAdded = true;
        } else if (line.startsWith("+++") && fileAdded) {
            filesChanged++;
            fileAdded = false;
        } else if (line.startsWith("+")) {
            additions++;
            fileAdded = false;
        } else if (line.startsWith("-")) {
            deletions++;
            fileAdded = false;
        } else {
            fileAdded = false;
        }

    }

    diff.additions = additions;
    diff.deletions = deletions;
    diff.changedFiles = filesChanged;

    return diff;
}

编辑2 如果你想了解一些背景信息,你可以引用这个Related question

最佳答案

我目前使用的是平板电脑,所以我帮不了什么忙,但是你的 Perl 需要一些改进。

您不应该使用for $line ( <> )因为它将在开始迭代之前尝试将所有输入读取到列表中。您也不使用 $line所以你应该直接阅读$_

while ( <> ) { ... }

也没有必要chomp每行,我不明白你为什么打电话 print每条记录?在chomp之后因此输出将是输入的副本,所有内容都在很长的一行上,并且聚合值位于最后。

我怀疑 Perl 脚本接收数据的情况很好,但无法将所有输入一次性装入内存,并将所有内容的第二个副本作为输出!

关于java - 将 ByteArrayOutputStream 发送到 Perl 脚本,然后读取响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38648302/

相关文章:

Java多线程-无需等待的锁定

macos - Perlbrew 找不到 @INC

perl - 在 Perl 中处理美元计算的最佳技术是什么?

c - 流缓冲是什么意思?

c++ - cout 输入模板

java - 如何通过单击按钮更改 javafx 中文本框的语言?

java - 从字节数组创建 8 位图像

java - 如何在ActionBar中设置返回按钮?

mysql - DBIx::Class:计算相关表中具有特定值的条目

string - java 8 String.chars() 是否可以正确处理 8 字节字符?