我有一个我从执行差异收到的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
答案 0 :(得分:1)
我目前正在使用平板电脑,所以我无法提供太多帮助,但您的Perl需要一些工作。
您不应该使用for $line ( <> )
,因为在开始迭代之前,它会尝试将输入的所有读入列表。您也不能使用$line
,因此您应该直接阅读$_
while ( <> ) { ... }
也没有必要chomp
每一行,我不明白为什么你为每条记录打电话给print
?它位于chomp
之后,因此输出将是一个非常长的行上的输入的副本,最后的聚合值。
我怀疑Perl脚本接收的数据很好,但是无法将所有输入同时输入到内存中,还有第二个副本作为输出!
答案 1 :(得分:0)
使用ByteArrayOutputStream
意味着diff的整个结果需要一次性存储在内存中,而不是以块的形式进行处理和垃圾收集。由于内存不足以及始终执行垃圾收集,您的Java程序可能会很慢。
如果您需要性能,则应优化Java代码,而不是创建对Perl的依赖。