【发布时间】:2019-07-25 18:44:13
【问题描述】:
我是 JAVA 新手,还没有找到一种方法来编写一个“hello world”应用程序,该应用程序在所有平台上都可以正常工作而无需任何更改,还可以检测和处理输出错误。
特别是,我想将以下可移植的 C 程序移植到 JAVA:
“生成文件”:
.POSIX:
TARGETS = hello
.PHONY: all clean
all: $(TARGETS)
clean:
-rm $(TARGETS)
“你好.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”的正确和可移植的实现已经超过了这个“一次编写,到处运行”平台的能力,那将是相当令人震惊的。
所以请帮助我创建一个行为与 C 版本完全相同并且仍然可移植的 JAVA 实现。
感谢 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());
}
}
}
但是,这并不是真正可移植的,因为它只能在提供“假”实用程序的 POSIX 系统上可靠地工作。
否则它将恢复为 99 的任意返回码,这显然是危险的,因为例如,某些平台可以将所有负值定义为失败代码,将所有其他值定义为成功代码。
【问题讨论】:
-
@khelwood 还没有。但正如文档所说“当底层输出流抛出 IOException 时,内部错误状态设置为 true”,并且 JAVA 编译器坚持不抛出此类异常,这似乎值得怀疑。不过我会试试的。
-
不,编译器对象,因为 IOException 永远不会被抛出 您正在调用的方法。这并不意味着它不能发生在方法内部(直接或间接)并在内部处理。
标签: java runtime-error portability system.out correctness