Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
To execute process/command in bash from java one can use the following class:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
public class CmdExecutor {
public CmdExecutor(){
}
public void exe(String [] args) throws IOException{
if (args.length <= 0) {
System.out.println("empty command");
return;
}
Process process = new ProcessBuilder(args).start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
System.out.printf("Output of running %s is:",
Arrays.toString(args));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
However. What if the process don't terminate(yet). It does calculations and output it in the shell. I want to be able to run the process in another thread and get changes in the output, like frame by frame strings. How can this be achieved?
Check out
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/LinkedBlockingQueue.html
You may want to have one thread (producer) reading process output, and putting them into a LinkedBlockingQueue (queue.put), then have another thread (consumer) to get elements from the queue (queue.poll) and process it.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I'm trying to get a copy of the content from the stream without consuming it. My plan is to use this original stream in the later of the code. Following is the sample code I tried to check this. My intention is to keep the original InputStream for future use after getting a copy
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
public class StreamTest {
public static void main(String[] args) {
try {
InputStream inputstream = new FileInputStream("resource.txt"); // content of the file is 'test'
ByteArrayOutputStream baos = new ByteArrayOutputStream();
org.apache.commons.io.IOUtils.copy(inputstream, baos);
byte[] bytes = baos.toByteArray();
System.out.println("copied stream : " + new String(bytes));
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(inputstream));
String line;
while ((line = br.readLine()) != null) {
sb.append(line + System.lineSeparator());
}
System.out.println("original stream : " + sb.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
but still, when I access the original stream, after coping it, I still see that the original stream is consumed. See below output
copied stream : test
original stream :
Can someone point out my mistake
Thanks
Sadly this is not possible by the nature of streams.
In order to copy the data from the stream, you need to first extract it. By extracting it, you consume the stream.
But do not worry, there should be a solution for your specific use case. Maybe open another stream (if you know the source of the stream gives the same data every time - as in a file - , you can use Supplier everywhere you would use the InputStream, so that a new stream is created whenever necessary), or you can check out this post for creating more streams with the same data: https://stackoverflow.com/a/5924132/3102234
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Goal: to initialise a JVM(2) from a separate JVM(1) using ProcessBuilder, capturing the resulting output from JVM(2) and displaying the result within a JTextArea in JVM(1).
Situation: able to launch JVM(2) from within JVM(1) and capture the resulting output from JVM(2) to a JTextArea within the JVM(1).
Problem: the JVM(2) will not respond to input until JVM(1) is terminated.
Thread inside VJM(1) that starts JVM(2):
Runnable runnable = () -> {
try {
JVMBooter.startSecondJVM();
} catch (Exception ex) {
Logger.getLogger(MyMenu.class.getName()).log(Level.SEVERE, null, ex);
}
};
Thread t = new Thread(runnable);
t.start();
JVMBooter source code:
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
public class JVMBooter {
public static void startSecondJVM() throws Exception {
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "startscript.bat");
File dir = new File("D:/Server");
pb.directory(dir);
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
( (line = reader.readLine()) != null && ! line.trim().equals("--EOF--")) {
OutputFrame.textArea.append(line + "\n");
}
}
}
The JVM(2) is started within the startscript.bat file with:
java -jar server.jar
Depending on the situation it may be necessary to read the error stream instead of the input stream, e.G. if your second java call is -version or the program you call only writes to stderr instead of stdout getting the Error Stream is the correct approach.
I wrote this MCVE:
import java.io.*;
public class Starter {
public static void main(String[] args) throws IOException {
ProcessBuilder pb = new ProcessBuilder("./dosomething.sh");
File dir = new File(new File(File.listRoots()[0], "tmp"), "2jvm");
pb.directory(dir);
Process p = pb.start();
BufferedReader read = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line;
while ( (line = read.readLine() ) != null) {
System.out.println("line: " + line);
}
}
}
and in 'dosomething.sh' this:
echo before
java -version
echo after
when I use p.getInputStream I would get the 'before' and 'after'. When I use p.getErrorStream I get the Java Version Information.
That might be true for you too. I suggest you add echo lines in your batch file to see if they get printed out.
I also wrote a simple hello world and when I called that from dosomething.sh it got printed to the input stream as expected. It is a weird quirk of -version to write to stderr.
For completeness here is the Hello World I used (it has waits to simulate a longrunning server process):
public class Caller {
public static void main(String[] args) {
synchronized(Caller.class) {
for(int ii = 0; ii < 10; ii++) {
try {
Caller.class.wait(1000);
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("Hello world! " + ii);
}
}
}
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have a C++ program which uses command line as its mean for IO. I don't know C++, nor do I have the program's source code. I want my java application to open the C++ program , give some input and gather the result from the C++ code. Is there a way?
UPDATE: I need to enter the input at runtime.
You can use java.lang.Runtime
For example:
public class TestRuntime {
public static void main(String[] args) {
try {
Process p = Runtime.getRuntime().exec("test.bat");
// test.bat or test.sh in linux is script with command to run (c++) program
// or direct path to application's exec
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
In addition, you can read about difference between Runtime and ProcessBuilder in this topic.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I want to do a socket connection for client and server to display the list of files. but below code is not taking any input from server or giving output to client. Please help.
Server
package javaapplicationthread;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
public class zs {
public static int reads,red;
public static void main(String[] args)
{
int flg=0;
try{while(true){
ServerSocket serverSocket = new ServerSocket(1312);
Socket clientSocket = serverSocket.accept();
BufferedReader bufferedReader;
PrintWriter outk=new PrintWriter(clientSocket.getOutputStream(),true);
bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine = bufferedReader.readLine();
System.out.println("input is"+ inputLine);
outk.write("abc");
File inputFolder = new File(inputLine);
System.out.println("control is being sent to traverse");
traverse(inputFolder, "");
}
}
catch (IOException ex) {
System.out.println("my exception is"+ex)
System.out.println(leftIndent + parentNode.getName());
}
}}
In the client, when you do redd = b.readLine(); you are asking to read an entire line. But in the server you haven't sent an entire line: you've only asked it to write three characters:
outk.write("abc");
None of those three characters is actually sent, however, because the PrintWriter buffers them temporarily. To fix it, change that line to:
outk.println("abc");
Or:
outk.write("abc\n");
outk.flush();
After that change, the client successfully displays: result is abc.
it is not giving any errors
They're both giving errors... The client throws an exception when the readLine call fails. The server throws an exception when it begins the next iteration of the while(true) loop and tries to recreate the socket it is still using. You probably want to move the creation of the ServerSocket outside the while loop.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am trying to write a program that just reads and write an unbuffered steam, and reads and writes a buffered stream. Following the example on the java docs, I've got this for my buffered stream, which works fine.
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyCharacters {
public static void main(String[] args) throws IOException {
FileReader inputStream = null;
FileWriter outputStream = null;
try {
inputStream = new FileReader("unbufferedread.txt");
outputStream = new FileWriter("unbufferedwrite.txt");
int c;
while ((c = inputStream.read()) != -1) {
outputStream.write(c);
}
// Add finally block incase of errors.
// Display error if input file is not found.
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}
However the Java docs say "Here's how you might modify the constructor invocations in the CopyCharacters example to use buffered I/O:".
inputStream = new BufferedReader(new FileReader("bufferedread.txt"));
outputStream = new BufferedWriter(new FileWriter("bufferedwrite.txt"));
My question is how to implement it. Is it possible to add it all to one class? When I try to add it, I get an error saying:
"Cannot find symbol - class BufferedReader"
Any help would be great. Thanks.
You have to import the java.io.BufferedReader and java.io.BufferedWriter classes. Based on the code you posted, you aren't doing that. So just add the two lines:
import java.io.BufferedReader;
import java.io.BufferedWriter;