Как стать автором
Обновить

Комментарии 17

При переходе от 7 к 8 потерялась обработка exception'ов, что, конечно же, уменьшает количество кода:)
Просто автор сам себе этим слегка так противоречит «Мораль: если у вас современная Java — надо делать хорошо, и не надо плохо.»
В 9й версии будет как на картинке «sudo bring beer», и JDK сама напишет код с нуля. В 10й можно будет нарисовать мышкой схематику работы, а в 11й введут пластиковые «кубики от 3х лет» для джуниор и сеньор программистов и искоренят понятие говнокода, так весь код будет говно, и котлеты пропадут.
И вообще: «Я согласен, подготовка программистов — гиблое дело. И вообще, скоро программистов можно будет заменить компьютером, чтобы он писал код» (директор центра стратегических инноваций «Ростелекома» Борис Глазков).
Но ведь кто-то будет писать код для компьютера, который будет писать код // Inception

Ждем появление сверх языка или буст asm?
Мораль: если у вас современная Java — надо делать хорошо, и не надо плохо.

Нет, не та мораль. Нужна такая — Мораль: Цените свое время, читайте только интересные статьи, шлак фильтруйте.
Я для чтения строк из файла использую класс Scanner с методами hasNextLine() + nextLine().
Который как раз при использовании regexp'а по-умолчанию (LINE_PATTERN) для 'hasNextLine()' и 'nextLine()' очень любит внезапно спотыкаться ;)
Обычно я использую его только для чтения файла построчно и соответственно не использую regexp. Остальные методы чтения файла построчно у меня иногда выдавали некорректный результат на различных ОС, на одной работало, на другой нет.
Вот как раз при построчном чтении там и есть regexp'ы под капотом, для определения строки которую нужно вернуть при вызове 'nextLine()'.
Поэтому Scanner все же стоит использовать аккуратно в отличие от прочих методов.
Содержит много сарказма, не читать java-программистам
Обожемой! В Java наконец-то можно прочитать файл «без подключения сторонних библиотек»! И теперь с лямбдой и неким Stream API! И наконец-то в одну строку, а не в 25!
Могуч язык, что сказать. Нам с нашими питонами-руби не угнаться…

Ну не могу еще раз не вставить эту картинку, уж извините…
image
Фреймворки — они такие, особенно в кривых умелых руках.
Есть такое. Но смотреть свысока на java будет близорукостью… Хотя бы потому что #1 по использованию и востребуемостии.

> Нам с нашими питонами-руби не угнаться…
Сарказм, да, читается. Вообще — область применения разная. Там где надо без этой портянки за одну строчку что то написать — конкурировать трудно, но, как видите, уже можно. Тот же Play вместо Django.
А вот что то тяжелее- проект на 10^6 строк, где размер стека уже не так важен — увы для питон-руби…
Почему-то IntelliJ Idea ругается на необработанное исключение, при использовании последнего примера. Похоже, это неполноценное решение.

Если бы только это…
Stream, который тут неявно создаётся, должен быть закрыт вызовом метода close() (от чего, конечно, спасёт try-with-resources, но ещё удобнее Lombok`овская аннотация @Cleanup)
Кроме того, вариант для Java 8 плох тем, что часто у нас нет абсолютного пути файла, только его имя и уверенность, что он лежит где-то в CLASSPATH (так бывает, если он в папке "src/main/resources" или для тестов — "src/test/resources" — в Maven-Gradle проектной структуре), так что гораздо удобнее использовать для поиска ClassLoader.
В общем, у меня получилось так (Java 8+ и не забываем подключить в проект Lombok):


class MyClass {
    @SneakyThrows
    public static void doWithFileLines(String fileName, Consumer<String> stringConsumer) {
        @Cleanup
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(
                       MyClass.class.getResourceAsStream(fileName), UTF_8));
        String line;
        while ((line = reader.readLine()) != null)
            stringConsumer.accept(line);
    }

    // Файл с таким именем должен лежать в ./src/test/resources в проекте
    static final String FILE_NAME = "/text.txt";

    // Дёргаем так:
    @Test
    @DisplayName("doWithFileLines method works correctly")
    void testDoWithFileLines() {
        doWithFileLines(FILE_NAME, line -> {
            // Здесь пишем, что надо делать с каждой строчкой,
            // например что бы вывести на консоль:
            System.out.println(line);
        });
    }
}
В Java 11 появился-таки простой метод считывания файла в строку — Files::readString, а так же записи в файл из строки — Files::writeString. Правда, остаётся проблема — как заюзать classloader для поиска файла, что бы не заморачиваться относительными и абсолютными путями, если знаешь, что файл в classpath’е (например, в папке ./src/main/resources проекта)? Решение придумал только такое — у кого получится более элегантно — напишите. У меня (с Lombok’ом и Vavr’ом) получилось так:
@SneakyThrows
public Optional<String> getFileAsString(String fileName) {
  val path = String.format("/%s", fileName);
  return Optional.ofNullable(getClass().getResource(path))
    .map(URL::getFile)
    .map(Paths::get)
    .map(CheckedFunction1.<Path, String>narrow(Files::readString)
      .recover(throwable -> null));
}
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации