Можно ли написать корректный и переносимый консольный вывод "hello world" в JAVA? - PullRequest
0 голосов
/ 04 марта 2019

Я новичок в 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, что, очевидно, опасно, потому что какая-то платформа может, например, определить все отрицательные значения как коды ошибок, а все остальные значения как коды успеха.

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

System.out - это PrintStream.

Документы для PrintStream говорят:

В отличие от других выходных потоков, a PrintStreamникогда не бросает IOException;вместо этого в исключительных ситуациях просто устанавливается внутренний флаг, который можно проверить с помощью метода checkError.

Вы можете проверить System.out.checkError(), чтобы увидеть, произошла ли ошибка.

Если вы хотите, чтобы ваша программа выходила с ненулевым статусом, вы можете использовать System.exit.

Например

if (System.out.checkError()) {
    System.err.println("An output error occurred.");
    System.exit(-1);
}

См. Также Есть ли замена для EXIT_SUCCESS и EXIT_FAILURE в Java?

0 голосов
/ 04 марта 2019

Объект System.out является экземпляром java.io.PrintStream .Вы можете использовать checkError() для проверки возможных ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...