Чтение текстового файла в парадигме продюсера - PullRequest
0 голосов
/ 03 апреля 2020

В парадигме продюсера есть задача прочитать текстовый файл. Интерфейс производителя определяется следующим образом:

public interface Producer<ITEM> {
    /**
     * Produces the next item.
     *
     * @return produced item
     */
    ITEM next();

    /**
     * Tells if there are more items available.
     *
     * @return true if there are more items, false otherwise
     */
    boolean hasNext();
}

Текущий код для чтения текстового файла:

public static void readTextFile(File file, Charset charset, Consumer<String> consumer) {
    try (InputStreamReader isr = new InputStreamReader(new FileInputStream(file), charset);
         BufferedReader in = new BufferedReader(isr, BUFFER_SIZE)) {
        String line;

        while ((line = in.readLine()) != null) {
            consumer.accept(line);
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

Задача - преобразовать его в:

public static Producer<String> readTextFileRetProducer(File file, Charset charset) {
    // ???

    return null;
}

Далее идет список проблем:

  1. Как правильно поддерживать hasNext , учитывая, что требуется заранее прочитать текстовую строку.
  2. Как правильно управлять исключениями?
  3. Как правильно высвобождать внешние ресурсы, если в парадигме производителя более недоступен удобный блок try-with-resources?

PS Ресурсы предназначены для быть освобожденным после прочтения последней строки из файла. (Он создается после).

PPS Если есть библиотеки и / или ссылки на код, которые я мог бы использовать в качестве руководства для своей задачи, пожалуйста, поделитесь ими.

1 Ответ

1 голос
/ 03 апреля 2020

Быстро и грязно:

public static Producer<String> readFile(File file, Charset charset) {
    Stream<String> stream;
    try {
        stream = Files.lines(file.toPath(), charset);
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
    Iterator<String> iter = stream.iterator();
    return new Producer<String>() {
        @Override
        public boolean hasNext() {
            if (!iter.hasNext()) {
                stream.close();
                return false;
            }
            return true;
        }
        @Override
        public String next() {
            return iter.next();
        }
    };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...