簡體   English   中英

為什么 Java 中的 System.out.println() 會打印到控制台?

[英]Why does System.out.println() in Java print to the console?

我在網上閱讀了幾篇文章,解釋了 Java 中的System.out.println()是什么。 他們中的大多數 go 像這樣:

  • System是java.lang package中的final java.lang
  • out是類型為PrintStreamSystem class 內的public static object 。
  • println()將一行文本打印到 output stream。

我的問題是當我們在代碼中執行System.out.println()時,為什么它最終會寫入控制台? 本文解釋了我們如何通過調用System.setOut()將其寫入文件。 所以我的問題轉化為調用System.setOut()以將其 output 重定向到控制台的位置?

我檢查了System.setOut()source 它調用native方法setOut0() 此方法在initializeSystemClass()方法中直接調用,方法是將 fdOut 傳遞給它, fdOut此處定義的FileOutputStream 我沒有在任何地方找到傳遞給setOut0()的控制台 output stream,也沒有在任何地方找到對非本地setOut()的調用。 它是否在開始執行時由 JVM 在System class 之外的其他地方完成? 如果是這樣,有人可以指出我嗎?

我的疑問是當我們在代碼中執行System.out.println()時,為什么它最終會寫入控制台?

在任何符合 POSIX 的 shell 中,當 shell 啟動時,每個進程都會獲得三個“標准”流:

  • “標准輸入” stream 用於讀取輸入。
  • “標准輸出”stream是寫普通output用的。
  • “標准錯誤” stream 用於寫入錯誤 output。

(同樣的想法也用於許多非 POSIX 兼容的 shell。)

對於交互式POSIX shell,默認情況下這些流可以讀取和寫入 shell 的“控制台”......這可能是物理控制台,但更有可能是用戶(最終)上的“終端模擬器”台式機。 (細節有所不同。)

POSIX shell 允許您以各種方式重定向標准流; 例如

$ some-command < file     # read stdin from 'file'
$ some-command > file     # write stdout to 'file'
$ some-command 2> file    # write stderr to 'file'
$ some-command << EOF     # read stdin from a 'here' document
  lines of input
  ...
  EOF
$ some-command | another  # connect stdout for one command to
                          # stdin for the next one in a pipeline

等等。 如果您這樣做,一個或多個標准流不會連接到控制台。

進一步閱讀:


那么這與問題有什么關系呢?

當一個Java程序啟動時, System.in/out/err /out/err流連接到父進程指定的標准輸入/output/錯誤流; 通常是 shell。

System.out的情況下,它可能是控制台(無論您如何定義),也可能是一個文件、另一個程序或... /dev/null 但是 output 的去向取決於 JVM 的啟動方式。

因此,字面上的答案是“因為這是父進程告訴 Java 程序要做的事情”。


How internally shell communicates with jvm to set standard input / output in both Windows and Linux?

這就是 Linux、UNIX、Mac OSX 和類似設備會發生的情況。 (我不知道 Windows ......但我想它是相似的。)

假設 shell 將運行aaa > bbb.txt

  1. 父 shell 分叉一個子進程...共享父 shell 的地址空間。
  2. 子進程關閉文件描述符1(標准output文件描述符)
  3. 子進程打開“bbb.txt”以寫入文件描述符 1。
  4. 子進程執行“aaa”命令,成為“aaa”命令進程。 文件描述符 0、1 和 2 由 exec 調用保留。
  5. “aaa”命令開始...

當“aaa”命令啟動時,它發現文件描述符 0 和 2(stdin 和 stderr)引用了與父 shell 相同的“文件”。 文件描述符 1 (stdout) 指的是“bbb.txt”。

當“aaa”是java命令時,也會發生同樣的事情。

它不需要。 我們可以重定向到其他地方。 這是重定向到文件的代碼:

PrintStream output = new PrintStream(new File("output.txt"));
System.setOut(output);
System.out.println("This will be written to file");

默認情況下,控制台是Java中的標准output stream(System.in)。

System.out.println不打印到控制台,它打印到標准 output streamSystem.out是 Java 的標准 output 流的名稱)。 標准的 output stream 通常是控制台,但並非必須如此。 The Java runtime just wraps the standard output stream of the operating system in a nice Java object.

A non-interactive program often uses a few standard input and output channels: it reads input from the standard input stream, does some operations on it, and produces output on the standard output stream. 標准 output stream 可以是控制台,但也可以通過管道傳輸到另一個程序的標准輸入 stream 或文件。 最后,運行編程的操作系統決定了標准 output stream output 是什么。

例如,在 Unix 終端中,您可以執行以下操作:

java -jar your.program.jar > output.txt

並將程序的 output 存儲在文本文件中,或

java -jar your.program.jar | grep hello

僅顯示包含“hello”的 output 的行。 僅當您不指定其他目的地時,標准 output stream 才會寫入控制台。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM