是否可以在 JAVA 中编写正确且可移植的控制台输出 "hello world"?
Is it possible to write a correct and portable console-output "hello world" in JAVA?
我是 JAVA 的新手,还没有找到编写 "hello world" 应用程序的方法,该应用程序无需任何更改即可在所有平台上正常工作,并且还可以检测和处理输出错误。
特别是,我想将以下可移植 C 程序移植到 JAVA:
"Makefile":
.POSIX:
TARGETS = hello
.PHONY: all clean
all: $(TARGETS)
clean:
-rm $(TARGETS)
"hello.c":
#include <stdio.h>
#include <stdlib.h>
int main(void) {
if (puts("Hello, world!") >= 0 && fflush(0) == 0) return EXIT_SUCCESS;
(void)fputs("An output error occurred.\n", stderr);
return EXIT_FAILURE;
}
此程序旨在像这样工作:
$ make
c99 -O hello.c -o hello
$ ./hello
Hello, world!
$ ./hello > /dev/full
An output error occurred.
不幸的是,我还不能在 JAVA 中实现相同的功能。
System.out.println() 和 System.out.flush() 似乎都没有检查 I/O 错误,或者我只是没能发现它们。
我已经尝试捕获 IOException 类型的异常,但编译器告诉我
error: exception IOException is never thrown in body of corresponding try statement
所以这显然不是正确的方法。
但即使我能找到一种方法来捕获输出错误,我仍然不知道可移植地使用什么退出代码,因为 JAVA 似乎没有定义与 C 的 EXIT_FAILURE 相对应的东西.
我很难相信,考虑到 JAVA 一直被誉为应用程序开发的高度可移植系统。
如果即使是一个简单的 "hello world" 的正确和可移植的实现已经超过了这个 "write once, run everywhere" 平台的能力,那将是非常令人震惊的。
所以请帮我创建一个 JAVA 实现,它的行为与 C 版本完全一样,并且仍然可移植。
感谢 khelwood 和其他人,我设法创建了以下 JAVA 目前效果最好的实现:
public class HelloWorld {
private static class OutputError extends java.io.IOException { }
private static void println(String s) throws OutputError {
System.out.println(s);
if (System.out.checkError()) throw new OutputError();
}
private static void flush() throws OutputError {
System.out.flush();
if (System.out.checkError()) throw new OutputError();
}
private static int getExitFailureCode() {
try {
return (new java.lang.ProcessBuilder("/bin/false")).start().waitFor();
} catch (Exception dummy) {
return 99;
}
}
public static void main(String[] args) {
try {
println("Hello, world!");
flush();
} catch (OutputError dummy) {
System.err.println("An output error occurred.");
System.exit(getExitFailureCode());
}
}
}
但是,这并不是真正的可移植,因为它只能在提供 "false" 实用程序的 POSIX 系统上可靠地工作。
否则它将恢复为任意 return 代码 99,这显然是危险的,因为某些平台可能会,例如,将所有负值定义为失败代码,将所有其他值定义为成功代码。
对象 System.out
是 java.io.PrintStream 的实例。您可以使用 checkError()
检查可能的错误。
System.out
是 PrintStream
.
PrintStream
的文档说:
Unlike other output streams, a PrintStream
never throws an IOException
; instead, exceptional situations merely set an internal flag that can be tested via the checkError
method.
您可以检查 System.out.checkError()
以查看是否发生了错误。
如果你想让你的程序以非零状态退出,你可以使用System.exit
.
例如
if (System.out.checkError()) {
System.err.println("An output error occurred.");
System.exit(-1);
}
另见 Is there a replacement for EXIT_SUCCESS and EXIT_FAILURE in Java?
我是 JAVA 的新手,还没有找到编写 "hello world" 应用程序的方法,该应用程序无需任何更改即可在所有平台上正常工作,并且还可以检测和处理输出错误。
特别是,我想将以下可移植 C 程序移植到 JAVA:
"Makefile":
.POSIX:
TARGETS = hello
.PHONY: all clean
all: $(TARGETS)
clean:
-rm $(TARGETS)
"hello.c":
#include <stdio.h>
#include <stdlib.h>
int main(void) {
if (puts("Hello, world!") >= 0 && fflush(0) == 0) return EXIT_SUCCESS;
(void)fputs("An output error occurred.\n", stderr);
return EXIT_FAILURE;
}
此程序旨在像这样工作:
$ make
c99 -O hello.c -o hello
$ ./hello
Hello, world!
$ ./hello > /dev/full
An output error occurred.
不幸的是,我还不能在 JAVA 中实现相同的功能。
System.out.println() 和 System.out.flush() 似乎都没有检查 I/O 错误,或者我只是没能发现它们。
我已经尝试捕获 IOException 类型的异常,但编译器告诉我
error: exception IOException is never thrown in body of corresponding try statement
所以这显然不是正确的方法。
但即使我能找到一种方法来捕获输出错误,我仍然不知道可移植地使用什么退出代码,因为 JAVA 似乎没有定义与 C 的 EXIT_FAILURE 相对应的东西.
我很难相信,考虑到 JAVA 一直被誉为应用程序开发的高度可移植系统。
如果即使是一个简单的 "hello world" 的正确和可移植的实现已经超过了这个 "write once, run everywhere" 平台的能力,那将是非常令人震惊的。
所以请帮我创建一个 JAVA 实现,它的行为与 C 版本完全一样,并且仍然可移植。
感谢 khelwood 和其他人,我设法创建了以下 JAVA 目前效果最好的实现:
public class HelloWorld {
private static class OutputError extends java.io.IOException { }
private static void println(String s) throws OutputError {
System.out.println(s);
if (System.out.checkError()) throw new OutputError();
}
private static void flush() throws OutputError {
System.out.flush();
if (System.out.checkError()) throw new OutputError();
}
private static int getExitFailureCode() {
try {
return (new java.lang.ProcessBuilder("/bin/false")).start().waitFor();
} catch (Exception dummy) {
return 99;
}
}
public static void main(String[] args) {
try {
println("Hello, world!");
flush();
} catch (OutputError dummy) {
System.err.println("An output error occurred.");
System.exit(getExitFailureCode());
}
}
}
但是,这并不是真正的可移植,因为它只能在提供 "false" 实用程序的 POSIX 系统上可靠地工作。
否则它将恢复为任意 return 代码 99,这显然是危险的,因为某些平台可能会,例如,将所有负值定义为失败代码,将所有其他值定义为成功代码。
对象 System.out
是 java.io.PrintStream 的实例。您可以使用 checkError()
检查可能的错误。
System.out
是 PrintStream
.
PrintStream
的文档说:
Unlike other output streams, a
PrintStream
never throws anIOException
; instead, exceptional situations merely set an internal flag that can be tested via thecheckError
method.
您可以检查 System.out.checkError()
以查看是否发生了错误。
如果你想让你的程序以非零状态退出,你可以使用System.exit
.
例如
if (System.out.checkError()) {
System.err.println("An output error occurred.");
System.exit(-1);
}
另见 Is there a replacement for EXIT_SUCCESS and EXIT_FAILURE in Java?