我System.out.println()在网上阅读了几篇文章,解释了Java 中的内容。他们中的大多数是这样的:
Systemis afinalclass in thejava.langpackage.outis apublic staticobject inside theSystemclass of typePrintStream.println()prints a line of text to the output stream.
My question is when we do System.out.println() in our code, why does it end up writing to the console? This article explains how we can make it write to a file by calling System.setOut(). So my question translates to where is System.setOut() called to redirect its output to the console?
I checked System.setOut()'s source. It makes a call to setOut0() which is a native method. This method is directly called inside the initializeSystemClass() method by passing it fdOut which is a FileOutputStream defined here. I did not find a console output stream passed to setOut0() anywhere, nor did I find a call to the non-native setOut() done anywhere. Is it done somewhere else outside the System class by the JVM while starting execution? If so, can someone point me to it?
我的疑问是当我们
System.out.println()在我们的代码中这样做时,为什么它最终会写入控制台?
在任何符合 POSIX 的 shell 中,每个进程在 shell 启动时都会获得三个“标准”流:
(同样的想法也用于许多非 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
Run Code Online (Sandbox Code Playgroud)
等等。如果您这样做,一个或多个标准流将不会连接到控制台。
进一步阅读:
那么这与问题有什么关系呢?
当Java程序启动时,System.in/out/err流连接到父进程指定的标准输入/输出/错误流;通常是一个外壳。
在 的情况下System.out,这可能是控制台(无论您如何定义),也可能是一个文件、另一个程序或 ... /dev/null。但是输出的去向取决于 JVM 的启动方式。
所以,字面的答案是“因为这是父进程告诉 Java 程序要做的事情”。
shell 如何在内部与 jvm 通信以在 Windows 和 Linux 中设置标准输入/输出?
这就是 Linux、UNIX、Mac OSX 和类似的情况。(我不知道 Windows ......但我想它是相似的。)
假设 shell 将要运行aaa > bbb.txt。
当“aaa”命令启动时,它发现文件描述符 0 和 2(stdin 和 stderr)引用与父 shell 相同的“文件”。文件描述符 1 (stdout) 指的是“bbb.txt”。
当“aaa”是java命令时会发生同样的事情。