gpt4 book ai didi

java - 如何将大输出写入 Process getOutputStream?

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:18:53 24 4
gpt4 key购买 nike

我正在尝试使用 ProcessBuilder 和 Process 执行命令(例如 ps -ef | grep apache)。只要“ps -ef”的输出很小,代码就可以工作。但如果输出太大,程序就会挂起。有没有办法来解决这个问题?这是我的代码基于 [ http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html]

#### Program.java ####
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class Program {

private List<String> command;

public Program(String commandString) throws IOException {
this(commandString, null);
}

public List<String> getCommand() {
return this.command;
}

private void setCommand(String filename, String location, String commandString, List<String> parameters) throws IOException {
if(filename != null) {
commandString = new File(location, filename).getCanonicalPath();
}

this.command =
Collections.synchronizedList(new ArrayList<String>());

this.command.add(commandString);
if (parameters != null) {
for (String arg: parameters) {
command.add(arg);
}
}
}

public String[] run() throws IOException, InterruptedException {
return this.run(null);
}

public String[] run(String input) throws IOException, InterruptedException {
ProcessBuilder processBuilder = new ProcessBuilder(this.command);

List<String> commandList = processBuilder.command();

Process process = processBuilder.start();
if(input != null) {
PrintWriter writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(process.getOutputStream())), true);
writer.println(input);
writer.flush();
writer.close();
}
process.getOutputStream().close();
Gobbler outGobbler = new Gobbler(process.getInputStream());
Gobbler errGobbler = new Gobbler(process.getErrorStream());

Thread outThread = new Thread(outGobbler);
Thread errThread = new Thread(errGobbler);

outThread.start();
errThread.start();

outThread.join();
errThread.join();

int exitVal = process.waitFor();
System.out.println("PROCESS WAIT FOR: " + exitVal);

List<String> output = outGobbler.getOuput();

return output.toArray(new String[output.size()]);
}
}



#### CommandExecutor.java ####

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

public class CommandExecutor {

public List<List<Object>> programs;

public static void main(String[] args) {

try {
CommandExecutor ce = new CommandExecutor(args[0]);
String output = ce.run();
System.out.println("Command: " + args[0]);
System.out.println("Output: " + output);
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println(e.getLocalizedMessage());
e.printStackTrace();
} catch (InterruptedException ie) {
// TODO Auto-generated catch block
System.out.println(ie.getLocalizedMessage());
ie.printStackTrace();
}

}

public CommandExecutor(String command) throws IOException {
this.setPrograms(command);
}

private void setPrograms(String command) throws IOException {
this.programs = new ArrayList<List<Object>>();

//String cmdstring = "";
String[] commands = command.split("\\s*;\\s*");
for(String c: commands) {
//String subcmdstr = "";
String file = null;
String[] chainedCommands = c.split("\\s*\\|\\s*");
String lastCmd = chainedCommands[chainedCommands.length-1];
String[] fileCmd = lastCmd.split("\\s*>\\s*");
if(fileCmd.length > 1) {
chainedCommands[chainedCommands.length-1] = fileCmd[0];
file = fileCmd[1];
}
List<Object> l = new ArrayList<Object>();
for(String p: chainedCommands) {
/*if(subcmdstr.equals("")) {
subcmdstr = p;
}
else {
subcmdstr += " redirects to " + p;
}*/
String[] cmdparams = p.split(" ");
String cmd = cmdparams[0];
List<String> params = new ArrayList<String>();
for(int j = 1; j < cmdparams.length; j++) {
params.add(cmdparams[j]);
}
Program prog = new Program(cmd, params);
l.add(prog);
}
if(file != null) {
//subcmdstr += " redirects to file: " + file;
l.add(file);
}
this.programs.add(l);
//cmdstring += "new command: " + subcmdstr + "\n";
}
//System.out.println("Actual Command: " + command);
//System.out.println("Command String:\n" + cmdstring);
}

public String run() throws IOException, InterruptedException {
String output = "";

for(List<Object> l: this.programs) {
String[] out = new String[0];
int count = 0;
boolean filenotfound = true;
for(Object o: l) {
if(o instanceof Program) {
Program p = (Program) o;
if(count == 0) {
out = p.run();
}
else {
out = p.run(CommandExecutor.arrayToString(out));
}
}
else if(o instanceof String) {
PrintWriter f = new PrintWriter(new File((String)o));
f.print(CommandExecutor.arrayToString(out));
f.close();
filenotfound = false;
}
count++;
}
if(filenotfound) {
output += CommandExecutor.arrayToString(out);
}
}

return output;
}

public static String arrayToString(String[] strArray) {
String str = "";
for(String s: strArray) {
str += s;
}
return str;
}
}

谢谢,

四边形

最佳答案

好的,我让它工作了。下面是代码,给定一个命令列表,它将一个命令的输出通过管道传递给下一个命令。

/* 
####### PipeRedirection.java
*/

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

public class PipeRedirection {

public static void main(String[] args) throws FileNotFoundException {

if(args.length < 2) {
System.err.println("Need at least two arguments");
System.exit(1);
}

try {
String input = null;
for(int i = 0; i < args.length; i++) {

String[] commandList = args[i].split(" ");

ProcessBuilder pb = new ProcessBuilder(commandList);
//pb.redirectErrorStream(true);
Process p = pb.start();

if(input != null) {
PrintWriter writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(p.getOutputStream())), true);
writer.println(input);
writer.flush();
writer.close();
}

InputProcess.Gobbler outGobbler = new InputProcess.Gobbler(p.getInputStream());
InputProcess.Gobbler errGobbler = new InputProcess.Gobbler(p.getErrorStream());
Thread outThread = new Thread(outGobbler);
Thread errThread = new Thread(errGobbler);
outThread.start();
errThread.start();

outThread.join();
errThread.join();

int exitVal = p.waitFor();
System.out.println("\n****************************");
System.out.println("Command: " + args[i]);
System.out.println("Exit Value = " + exitVal);
List<String> output = outGobbler.getOuput();
input = "";
for(String o: output) {
input += o;
}
}
System.out.println("Final Output:");
System.out.println(input);

} catch (IOException ioe) {
// TODO Auto-generated catch block
System.err.println(ioe.getLocalizedMessage());
ioe.printStackTrace();
} catch (InterruptedException ie) {
// TODO Auto-generated catch block
System.err.println(ie.getLocalizedMessage());
ie.printStackTrace();
}

}


public static class Gobbler implements Runnable {
private BufferedReader reader;
private List<String> output;

public Gobbler(InputStream inputStream) {
this.reader = new BufferedReader(new InputStreamReader(inputStream));
}

public void run() {
String line;
this.output = new ArrayList<String>();
try {
while((line = this.reader.readLine()) != null) {
this.output.add(line + "\n");
}
this.reader.close();
}
catch (IOException e) {
// TODO
System.err.println("ERROR: " + e.getMessage());
}
}

public List<String> getOuput() {
return this.output;
}
}
}

关于java - 如何将大输出写入 Process getOutputStream?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1068713/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com