2013-10-01 167 views
2

我正在開發一個用於教學Python的Web應用程序,我必須解決的一個問題是如何從Jython解釋器中捕獲標準輸出,這一點在補充的時候就已經解決了。正確捕獲Jython輸出

目前我捕捉到輸出StringBuilder對象,但這種做法讓我只得到輸出時的代碼運行完畢:

PythonInterpreter interp = new PythonInterpreter(null, new PySystemState()); 
StringWriter out = new StringWriter(); 
interp.setOut(out); 
interp.exec(pyScript); 
String outputStr = out.toString(); 

我想吃點什麼,就是以後可運行代碼從瀏覽器收到,解釋器仍在後臺運行。如果代碼需要花費時間運行,但輸出被捕獲並存儲在數據庫中,讓Ajax代碼不斷接收有關輸出內容的更新。

+0

您是否嘗試過調用exec並從不同線程的OutputStream中讀取數據? – SimonC

+0

不,我沒有。我有這樣的想法,我可以創建自己的OutputStream類,不管寫到它的數據庫都會不擇手段地提交到數據庫,但是我希望避免它,因爲有足夠的方法可以阻止我這樣做。還有PythonInterpreter.setOut(PyObject outStream)方法,但我不確定如何使用它。 – Passiday

+1

查看http://docs.oracle.com/javase/7/docs/api/java/io/PipedOutputStream.html,如果您要從另一個線程的輸出流中讀取數據,您將使用它。請記住,在同一個線程中寫入數據庫可能會導致你的python代碼被阻塞(當然這可能是可以接受的)。 – SimonC

回答

1

寫我自己的OutputStream實現的男人竟然是要走的路。僅僅實現write()和flush()方法就足夠了。一些沿線的:

public class DBOutputStream extends OutputStream 
{ 
    private String buffer; 
    private DBConnClass db; 

    public DBOutputStream (DBConnClass dbConn) 
    { 
     buffer = ""; 
     db = dbConn; 
    } 

    public void write(int b) 
    { 
     byte[] bytes = new byte[1]; 
     bytes[0] = (byte) (b & 0xff); 
     buffer = buffer + new String(bytes); 

     if (buffer.endsWith("\n")) 
     { 
      buffer = buffer.substring (0, buffer.length() - 1); 
      flush(); 
     } 
    } 
    public void flush() 
    { 
     // Commit the buffer to db here 
     buffer = ""; 
    } 
} 

我想這比從另一個線程讀取OutputStream更穩定。現在只需要一個線程,即解釋器運行的線程就足夠了。