Я новичок в 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 (), кажется, проверяет наличие ошибок ввода-вывода, или, возможно, я просто не смог их перехватить.
Я уже пытался перехватывать исключения типа IOException, но компилятор сообщает мне, что
error: exception IOException is never thrown in body of corresponding try statement
, так что это явно не правильный способ сделать это.
Но даже если бы я мог найти способ отловить ошибки вывода, я все еще не мог понять, какой код выхода использовать переносимо, потому что JAVA не кажетсяопределить что-то соответствующее EXIT_FAILURE в C.
Мне трудно в это поверить, учитывая, что JAVA всегда хвалят как чрезвычайно портативную систему для разработки приложений.
Было бы весьма шокирующим, если бы правильная и переносимая реализация даже простого «привет-мира» уже превысилаВозможности этой платформы «пиши один раз, беги везде».
Поэтому, пожалуйста, помогите мне создать реализацию 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());
}
}
}
Однако это не совсем переносимо, потому что оно будет надежно работать только в системах POSIX, которые предоставляют утилиту "false".
В противном случае он вернется к произвольному коду возврата 99, что, очевидно, опасно, потому что какая-то платформа может, например, определить все отрицательные значения как коды ошибок, а все остальные значения как коды успеха.