How to know if the process has terminated while processing the inputstream and when should I call process.waitFor() or process.exitValue()?

huangapple go评论56阅读模式
英文:

How to know if the process has terminated while processing the inputstream and when should I call process.waitFor() or process.exitValue()?

问题

在尝试执行Java命令时,如果您使用BufferedReader将进程的InputStream转换为字符串,并在处理InputStream转换为字符串后调用process.waitFor(),则代码将正常工作。但是,当尝试使用ByteArrayOutputStream将进程的输入流转换为字符串时,如果在处理InputStream转换为字符串之后写入process.waitFor(),则不会返回结果。只有在调用process.waitFor()之前写入inputstream.isavailable()时才会正常工作。我不明白为什么会出现这种情况。另外,我想知道在使用ByteArrayOutputStream时如何确定缓冲区数组的大小。我尝试使用isavailable() 来确定字节数。

关于确定缓冲区大小的问题,您可以采用以下方式来动态确定ByteArrayOutputStream的缓冲区大小:

ProcessBuilder pb = new ProcessBuilder();
String cmd = "ls -l /Users/uma/data";
pb.command("bash", "-c", cmd);

try {
    Process process = pb.start();
    int exitVal = process.waitFor();
    InputStream is = process.getInputStream();
    ByteArrayOutputStream result = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024]; // 初始缓冲区大小,您可以根据需要进行调整
    int length;
    while ((length = is.read(buffer)) != -1) {
        result.write(buffer, 0, length);
    }
    String output = result.toString();
    if (exitVal == 0) {
        System.out.println("Success!");
        System.out.println(output);
        System.exit(0);
    } else {
        try (final BufferedReader b = new BufferedReader(new InputStreamReader(process.getErrorStream())) {
            String errorline;
            if ((errorline = b.readLine()) != null)
                System.out.println(errorline);
        } catch (final IOException e) {
            e.printStackTrace();
        }   
    }
} catch (IOException e) {
    e.printStackTrace();
}

关于何时调用waitFor(),通常您应该在处理进程的输出之前调用它,以确保进程已经完成执行。这样可以确保您在尝试读取进程输出时不会遇到问题。在上面的示例中,process.waitFor()在读取进程的输出之前被调用,以确保在继续之前等待进程的完成。

英文:

I am trying to execute commands using Java. So when I try to convert the process Inputstream to string using BufferedReader, the code works if I call process.waitFor() after processing the inputstream to string. But when I try to convert the process input stream using ByteArrayOutputStream to string, the results are not returned if I write process.waitFor() after processing the inputstream to string. It works only process.waitFor is written before inputstream.isavailable(). I don't understand why this is behaving like this? Also I want to know how to determing the buffer array size incase of using ByteArrayStream. I am trying to use isavailable() to know to number of bytes.

``ProcessBuilder pb = new ProcessBuilder();

	String cmd = "ls -l /Users/uma/data";
	pb.command("bash", "-c",cmd);
	
	try {
		Process process = pb.start();
		StringBuilder output = new StringBuilder();
		
		BufferedReader reader = new BufferedReader(
				new InputStreamReader(process.getInputStream()));

		String line;
		while ((line = reader.readLine()) != null) {
			output.append(line + "\n");
		}
		intexitVal = process.waitFor();

		if (exitVal == 0) {
			System.out.println("Success!");
			System.out.println(output);
			System.exit(0);
		} else {
			  try (final BufferedReader b = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
	                String errorline;
	                if ((errorline = b.readLine()) != null)
	                    System.out.println(errorline);
	            } catch (final IOException e) {
	                e.printStackTrace();
	            }   
		}
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	`

``ProcessBuilder pb = new ProcessBuilder();
		
		String cmd = "ls -l /Users/uma/data";
		pb.command("bash", "-c",cmd);
		
		try {
			Process process = pb.start();
			int exitVal = process.waitFor();
			InputStream is = process.getInputStream();
			 ByteArrayOutputStream result = new ByteArrayOutputStream();
		        byte[] buffer = newbyte[is.available()];
		        int length;
		        while ((length = is.read(buffer)) != -1) {
		            result.write(buffer, 0, length);
		        }
		        String output = result.toString();
			if (exitVal == 0) {
				System.out.println("Success!");
				System.out.println(output);
				System.exit(0);
			} else {
				  try (final BufferedReader b = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
		                String errorline;
		                if ((errorline = b.readLine()) != null)
		                    System.out.println(errorline);
		            } catch (final IOException e) {
		                e.printStackTrace();
		            }   
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}`

How to determine the buffer size? Also when should I call waitFor()?

答案1

得分: 0

waitFor() 等待目标进程退出,并返回其返回的退出代码。您可以使用它来等待程序停止,然后记录任何错误或检查退出代码。

至于缓冲区大小,如果您只想将整个输入流作为字节数组获取,我建议使用 is.readAllBytes()。然后,要将其转换为字符串,请使用 new String(is.readAllBytes());

如果您只想将输入流的内容流式传输到另一个流(如 System.out 或 System.err),请使用以下代码:

InputStream is = /* 获取输入流 */;
byte[] buffer = new byte[128];
int read;
while((read = is.read(buffer)) != -1) {
    System.out.write(buffer, 0, read);
}

这将仅将整个 is 输入流写入 System.out,您可以根据需要进行配置或更改。

英文:

waitFor() waits for the target process to exit, and returns the exit code given by it. You can use it to wait for the program to stop, before logging any errors or checking the exit code.

As for the buffer size, I recommend using is.readAllBytes() if you just want to get the entire input stream as a byte array. To then convert that to a string, use new String(is.readAllBytes());.

If you just want to stream the content of the input stream into another stream (such as System.out or System.err), use this:

InputStream is = /* get input stream */;
byte[] buffer = new byte[128];
int read;
while((read = is.read(buffer)) != -1) {
    System.out.write(buffer, 0, read);
}

This will just write the entire is input stream into System.out, you can configure or change this as you'd like.

huangapple
  • 本文由 发表于 2023年2月6日 17:12:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/75359317.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定