我有一个文件lowercase.perl,这需要一个文件作为输入,并以小写形式将其所有内容打印到另一个输出文件中。
use warnings;
use strict;
binmode(STDIN, ":utf8");
binmode(STDOUT, ":utf8");
while(<STDIN>) {
print lc($_);
}
我想从java
运行它import java.io.*;
public class Sample {
public static void main(String args[]) {
Process process;
try
{
process = Runtime.getRuntime().exec("perl lowercase.perl <lower.eng> lowerlm.eng");
process.waitFor();
if(process.exitValue() == 0)
{
System.out.println("Command Successful");
}
else
{
System.out.println("Command Failure");
}
}
catch(Exception e)
{
System.out.println("Exception: "+ e.toString());
}
}
}
但这不起作用。
我的所有文件都在同一个目录中,我也在同一个目录中运行终端。似乎正在发生的是perl脚本正在执行但输入参数 <lower.eng>
(这必须通过菱形运算符传递)我已经通过不正常工作。
我已直接运行perl脚本,如果不使用java运行它可以正常工作。
答案 0 :(得分:0)
您的描述中有点令人困惑的是
exec("perl lowercase.perl <lower.eng> lowerlm.eng");
... 输入参数
<lower.eng>
(这必须与钻石一起传递 我已经通过的运营商不能正常运作。
因为这意味着您希望文字字符串"<lower.eng>"
作为命令行参数。但是,在你的评论中你说
lowerlm.eng使用所有文本的小写版本进行编辑 来自lower.eng只有在直接运行perl命令时才会发生这种情况 不是在使用java
运行时
这意味着实际上<lower.eng
和>lowerlm.eng
是shell redirections。虽然Runtime.exec
的文档中没有明确说明,但Java似乎没有调用shell。
事实上,如果在你的Perl脚本中检查@ARGV
(例如通过将其写入文件),您将看到从Java调用的Perl脚本是使用命令行参数调用的{{1并且"<lower.eng>"
而不是重定向其输入和输出。
有几种可能的解决方案:
A. 使用Java ProcessBuilder
为您设置重定向,无论是文件还是文件,或者,如果您的输入和/或输出源自同一Java程序,请避免直接使用OutputStream
和InputStream
的临时文件。这不需要对Perl脚本进行任何修改。
"lowerlm.eng"
B。修改Perl脚本以接受命令行上的输入/输出文件名(例如Getopt::Long
,尽管下面我保持简单),所以你不要必须依赖shell重定向。
ProcessBuilder pb = new ProcessBuilder("perl", "lowercase.perl");
pb.redirectInput(new File("lower.eng"));
pb.redirectOutput(new File("lowerlm.eng"));
Process process = pb.start();
C。虽然我不建议这只是为了完整性:您可以从Java调用shell,例如use warnings;
use strict;
die "Usage: $0 INFILE OUTFILE\n" unless @ARGV==2;
my $INFILE = $ARGV[0];
my $OUTFILE = $ARGV[1];
open my $ifh, '<', $INFILE or die "$INFILE: $!";
open my $ofh, '>', $OUTFILE or die "$OUTFILE: $!";
while (<$ifh>) {
print $ofh lc;
}
close $ifh;
close $ofh;
。这不是一个好主意,因为你必须非常小心引用和所有shell元字符。