2016-10-29 80 views
0

我有一個Java應用程序,通過掃描儀讀取System.in輸入,並通過System.out提供輸出。掃描器始終處於活動狀態,不通過終端使用Ctrl + C或終止IDE中的進程就不會終止。System.out不刷新

我遇到了一些導致我相信System.out無法正常刷新的行爲。

在我的代碼有行:

System.out.print(",\\" + '\n'); 
System.out.print("  " + someString); 

(someString不包含換行符)

當我通過終端執行該代碼時,空白和someString不會被打印到所述終奌站。但是,在我的IDE控制檯中,它是。 (IntelliJ)

如果我將第二條語句更改爲println而不是print,它可以正常工作,但它在代碼的一次執行和下一次執行之間添加了新行,這在此處不可行。 (也許有什麼我可以做一個回車?)

這聽起來很像輸出沒有被刷新,因爲它唯一的System.out.print有麻煩。但是,在打印語句後添加System.out.flush()不會導致它打印。

+0

我真的不知道問題是什麼,但'System.out'沒有指明它是自動沖水的行爲;所以這取決於實施。顯然,在你的特定設置中,IntelliJ's和JAVA_HOME設置爲(猜測使用情況)的不同。 – user2478398

+0

可能是這種情況。我在Windows和Linux計算機上都嘗試過它,它們都具有相同版本的JDK。 – sudom82

+0

@ Sudom82您是否嘗試在我的回答中添加'\ r \ n'? – developer

回答

0

假設你在Windows中運行該程序,馬車 回報(\r)和換行(\n)一起需要添加打印 新線如下:

System.out.print(",\\" + '\r\n'); 
System.out.print("  " + someString); 
+0

這是旁白。基於換行符('\ n'')字符出現自動填充。 –

+0

@StephenC我認爲他的問題是'someString不包含換行符'(如果從終端運行),所以添加\ r \ n應該可以解決問題。 – developer

+0

@javaguy剛剛嘗試過你的建議,假設那些應該在第1行的\ r \ n附近加雙引號(否則會出現編譯器錯誤)。不幸的是,它沒有解決問題。如果有人調用另一個新行(通過println或print('\ n')),someString仍然不會被打印。 – sudom82

1

這聽起來很像輸出沒有被刷新,因爲它只有System.out.print有麻煩。

通常,System.outSystem.err配置不同。 (System.err通常不會被緩衝,並且通常會緩衝System.out。)但是,javadoc並未指定任何流的清空行爲。這可以解釋(實際)控制檯和在IDE中運行之間的行爲差​​異。

有關的信息,這裏是流如何在Java 8初始化:

FileInputStream fdIn = new FileInputStream(FileDescriptor.in); 
    FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); 
    FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err); 
    setIn0(new BufferedInputStream(fdIn)); 
    setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding"))); 
    setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding"))); 

private static PrintStream ewPrintStream(FileOutputStream fos, String enc) { 
    if (enc != null) { 
     try { 
      return new PrintStream(new BufferedOutputStream(fos, 128), 
            true, enc); 
     } catch (UnsupportedEncodingException uee) {} 
    } 
    return new PrintStream(new BufferedOutputStream(fos, 128), true); 
} 

正如你可以看到與啓用自動沖洗緩衝,System.out被初始化。


但是,打印語句後加入System.out.flush()不會導致它來打印。

您確定嗎? A flush()應該刷新任何緩衝輸出。

我認爲問題實際上是在別的地方;例如由於某種原因,printflush調用不會發生。


它也有可能是一些你們的問題是由於這樣的:

System.out.print(",\\" + '\n'); 

由於@javaguy指出,一個換行符是特定於平臺的行分隔符。在某些平臺上,控制檯需要不同的東西。最簡單的平臺獨立的方式來告訴控制檯做一個換行符是:

System.out.println(",\\"); 

或者把他們放在一起:

System.out.println(",\\"); 
System.out.print("  " + someString); 
System.out.flush(); // This is necessary ... and should work. 
+0

我已驗證System.out.flush()正在通過代碼覆蓋工具調用。我會仔細檢查這一點。 – sudom82

+0

代碼覆蓋工具不會給出正確的答案。它會告訴你,該方法被稱爲* somewhere *,而不是它被稱爲你感興趣的特定地方*。 (例如,當寫入換行符時,flush方法在引擎蓋下被調用。) –

+0

嗯,我只運行這一個方法的單個測試,並且我的代碼覆蓋工具用System.out.flush顯示了這個確切的行();正在執行,以及之前和之後的行。我可能會誤解它,但如果是這樣,我不知道如何。 – sudom82

0

的System.out.println()將光標置於下一行執行後。所以你不需要添加「\ n」。這可能就是爲什麼一線之間的空間。

只是這樣做:

System.out.println(",\\"); 
System.out.println("  " + someString); 
+0

這會打印所有輸出,但會在代碼執行之間添加一個空白的新行,這對我來說不是一個好選擇。 – sudom82