J
Jamaica R.
The DLL is c++ wrapping a Fortran subroutine, and called via JNI in
the Java Application. I need to read the standard output from Fortran
code, and display it to a dialog in Java Dialog. But using I/O
redirection :
System.setOut(new PrintStream(nativeDLL.getOutputStream()) ) can only
read Java's standout output, -- it doesn't work on my DLL's output...
Could you pls help me? Thanks in advance.
We can't use Process.getInputStream() since this is a DLL rather an
executable and the library is loaded without using Process, and a
class LoopedStreams is used to implement input stream.
public void run()
{
final LoopedStreams ls = new LoopedStreams();
PrintStream ps = new PrintStream(ls.getOutputStream());
System.setOut(ps);
System.setErr(ps);
try
{
LoadNativeDll.Init(m_command);
new LoadNativeDll(m_workingDir+"\\").start();
}
catch (Exception ex)
{//display ex
return;
}
final BufferedReader br = new BufferedReader(new
InputStreamReader(ls.getInputStream()));
new Thread(new Runnable()
{
public void run()
{
try
{
String line;
while ((line = br.readLine())!=null)
{
//feed the line to a dialog
sleep(10);
}
fireStatusEvent(this,
RegressionStatusEvent.REGRESSSION_STOP);
}
catch (Exception ex)
{//display ex
return;
}
}
}).start();
}
// now the LoopedStreams wrapper
public class LoopedStreams {
private PipedOutputStream pipedOS =
new PipedOutputStream();
private boolean keepRunning = true;
private ByteArrayOutputStream byteArrayOS =
new ByteArrayOutputStream() {
public void close()
{
keepRunning = false;
try {
super.close();
pipedOS.close();
}
catch(IOException e) {
// record error and deal with it
// here simply stop it
System.err.println("Fail to close
ByteArrayOutputStream!");
return;
}
}
};
private PipedInputStream pipedIS = new PipedInputStream() {
public void close() {
keepRunning = false;
try {
super.close();
}
catch(IOException e) { return; }
}
};
public LoopedStreams() throws IOException {
pipedOS.connect(pipedIS);
startByteArrayReaderThread();
} // LoopedStreams()
public InputStream getInputStream() {
return pipedIS;
} // getInputStream()
public OutputStream getOutputStream() {
return byteArrayOS;
} // getOutputStream()
private void startByteArrayReaderThread() {
new Thread(new Runnable() {
public void run() {
while(keepRunning) {
// check the bytes size of the stream
if(byteArrayOS.size() > 0) {
byte[] buffer = null;
synchronized(byteArrayOS) {
buffer = byteArrayOS.toByteArray();
byteArrayOS.reset(); // flush the buffer
}
try {
// send data to PipedOutputStream
pipedOS.write(buffer, 0, buffer.length);
}
catch(IOException e) {
// record error and deal with it
// here simply stop it
System.err.println("Read thread
error!");
return;
}
}
else // no data and turn the thread to sleep
try {
// check the ByteArrayOutputStream for new
data every 1s
Thread.sleep(1000);
}
catch(InterruptedException e) {}
}
}
}).start();
} // startByteArrayReaderThread()
} // LoopedStreams
the Java Application. I need to read the standard output from Fortran
code, and display it to a dialog in Java Dialog. But using I/O
redirection :
System.setOut(new PrintStream(nativeDLL.getOutputStream()) ) can only
read Java's standout output, -- it doesn't work on my DLL's output...
Could you pls help me? Thanks in advance.
We can't use Process.getInputStream() since this is a DLL rather an
executable and the library is loaded without using Process, and a
class LoopedStreams is used to implement input stream.
public void run()
{
final LoopedStreams ls = new LoopedStreams();
PrintStream ps = new PrintStream(ls.getOutputStream());
System.setOut(ps);
System.setErr(ps);
try
{
LoadNativeDll.Init(m_command);
new LoadNativeDll(m_workingDir+"\\").start();
}
catch (Exception ex)
{//display ex
return;
}
final BufferedReader br = new BufferedReader(new
InputStreamReader(ls.getInputStream()));
new Thread(new Runnable()
{
public void run()
{
try
{
String line;
while ((line = br.readLine())!=null)
{
//feed the line to a dialog
sleep(10);
}
fireStatusEvent(this,
RegressionStatusEvent.REGRESSSION_STOP);
}
catch (Exception ex)
{//display ex
return;
}
}
}).start();
}
// now the LoopedStreams wrapper
public class LoopedStreams {
private PipedOutputStream pipedOS =
new PipedOutputStream();
private boolean keepRunning = true;
private ByteArrayOutputStream byteArrayOS =
new ByteArrayOutputStream() {
public void close()
{
keepRunning = false;
try {
super.close();
pipedOS.close();
}
catch(IOException e) {
// record error and deal with it
// here simply stop it
System.err.println("Fail to close
ByteArrayOutputStream!");
return;
}
}
};
private PipedInputStream pipedIS = new PipedInputStream() {
public void close() {
keepRunning = false;
try {
super.close();
}
catch(IOException e) { return; }
}
};
public LoopedStreams() throws IOException {
pipedOS.connect(pipedIS);
startByteArrayReaderThread();
} // LoopedStreams()
public InputStream getInputStream() {
return pipedIS;
} // getInputStream()
public OutputStream getOutputStream() {
return byteArrayOS;
} // getOutputStream()
private void startByteArrayReaderThread() {
new Thread(new Runnable() {
public void run() {
while(keepRunning) {
// check the bytes size of the stream
if(byteArrayOS.size() > 0) {
byte[] buffer = null;
synchronized(byteArrayOS) {
buffer = byteArrayOS.toByteArray();
byteArrayOS.reset(); // flush the buffer
}
try {
// send data to PipedOutputStream
pipedOS.write(buffer, 0, buffer.length);
}
catch(IOException e) {
// record error and deal with it
// here simply stop it
System.err.println("Read thread
error!");
return;
}
}
else // no data and turn the thread to sleep
try {
// check the ByteArrayOutputStream for new
data every 1s
Thread.sleep(1000);
}
catch(InterruptedException e) {}
}
}
}).start();
} // startByteArrayReaderThread()
} // LoopedStreams