Search code examples
javajspprocessbuilder

ProcessBuilder.redirectOutput( myFile) is not updating the file right away but only updating after refresh


I am making an online code editor to run user typed codes only in 3 languages (c++,java,python) in JSP. So i am executing the command through process builder and storing the output of execution in a text file. But the output in text file is not being updated at that time but when again i submit the other code or i refresh the page then only cureent output is bieng updated in output text file. How to overcome this problem.

please help. Here is the code that i am using for executing c++ programs

File executed_output =new File(path+"C++\\executed_output.txt");
PrintStream o=new PrintStream(executed_output);
List<String>cmd_execute=new ArrayList<String>();

temp=ch+(path+"C++\\code_file.exe")+ch;
cmd_execute.add(temp);
 proc = new ProcessBuilder(cmd_execute)
.redirectErrorStream(true)
.directory(new File(path+"C++\\"))
.redirectErrorStream(true)
.redirectOutput(executed_output )
.start();
 
 proc.getInputStream().close();
proc.getOutputStream().close();

 proc.waitFor(1, TimeUnit.SECONDS);  
 proc.destroy();                     
proc.waitFor(1, TimeUnit.SECONDS);   
proc.destroyForcibly();             
proc.waitFor();


File ff=new File(path+"C++\\executed_output.txt");
FileReader fr=new FileReader(ff); 
BufferedReader br=new BufferedReader(fr);
String ln=br.readLine();  
out.println(ln);
//Scanner scc=new Scanner(ff);
while(ln!=null){
    out.println(ln);
    //out.println(ln);
    ln=br.readLine();
}

Solution

  • You are only giving the command one second to run, and then you call destroy before waitFor() so deleting these lines would allow the process more time to complete:

    proc.waitFor(1, TimeUnit.SECONDS);  
    proc.destroy();                     
    proc.waitFor(1, TimeUnit.SECONDS);   
    proc.destroyForcibly();
    

    As you are using .redirectErrorStream(true) and .redirectOutput(executed_output) to collect output to a file then you should delete this line too:

    proc.getInputStream().close();
    

    In case there is a second execution of same JSP at same time, your file needs to be different each time, call File.createTemporaryFile() or add a (counter++) to make unique filename instead of "executed_output.txt" every time:

    File executed_output =new File(path+"C++\\executed_output.txt")
    File ff=executed_output;
    

    Adding try with resources block would help clean up the open streams.