Эффективная обработка текста с использованием Java BufferedReader

JavaJavaBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом лабораторном задании мы будем использовать класс BufferedReader на Java, который является частью пакета java.io. BufferedReader используется для чтения текста из символьного входного потока и буферизирует символы для более высокой производительности. Класс оборачивает другие классы читателей и входные потоки, что позволяет нам повысить общую эффективность и производительность наших программ. Мы рассмотрим различные конструкторы, методы и сценарии использования BufferedReader, чтобы понять его функциональность.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/StringManipulationGroup(["String Manipulation"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java(("Java")) -.-> java/FileandIOManagementGroup(["File and I/O Management"]) java/StringManipulationGroup -.-> java/stringbuffer_stringbuilder("StringBuffer/StringBuilder") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/user_input("User Input") java/FileandIOManagementGroup -.-> java/files("Files") java/FileandIOManagementGroup -.-> java/read_files("Read Files") java/FileandIOManagementGroup -.-> java/io("IO") java/FileandIOManagementGroup -.-> java/stream("Stream") subgraph Lab Skills java/stringbuffer_stringbuilder -.-> lab-117473{{"Эффективная обработка текста с использованием Java BufferedReader"}} java/user_input -.-> lab-117473{{"Эффективная обработка текста с использованием Java BufferedReader"}} java/files -.-> lab-117473{{"Эффективная обработка текста с использованием Java BufferedReader"}} java/read_files -.-> lab-117473{{"Эффективная обработка текста с использованием Java BufferedReader"}} java/io -.-> lab-117473{{"Эффективная обработка текста с использованием Java BufferedReader"}} java/stream -.-> lab-117473{{"Эффективная обработка текста с использованием Java BufferedReader"}} end

Создание BufferedReader с использованием FileReader

Конструктор BufferedReader принимает объект Reader в качестве параметра. Мы можем создать читателя с использованием FileReader, который читает текстовые файлы в стандартной кодировке. В этом шаге мы будем читать файл с использованием класса BufferedReader, оборачивая FileReader.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderDemo {
    public static void main(String[] args) {
        String path = "path/to/your/file.txt";
        try {
            FileReader fileReader = new FileReader(path);
            BufferedReader bufferedReader = new BufferedReader(fileReader); //Создание BufferedReader путём оборачивания FileReader
            // Добавьте код для чтения данных из файла здесь

            bufferedReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Для запуска кода скомпилируйте файл с помощью javac BufferedReaderDemo.java, а затем запустите его с помощью java BufferedReaderDemo.

Использование BufferedReader с потоком

Мы также можем создать BufferedReader, используя входной поток в качестве источника. В этом шаге мы обернём InputStreamReader в BufferedReader и будем читать данные из System.in. Это позволит прочитать данные, которые мы вводим с клавиатуры.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BufferedReaderDemo {
    public static void main(String[] args) {
        try {
            InputStreamReader isr = new InputStreamReader(System.in);
            BufferedReader bufferedReader = new BufferedReader(isr); //Создание BufferedReader
            System.out.println("Enter Something:");
            String line = bufferedReader.readLine(); //Прочитать ввод с консоли
            System.out.println("You Entered: " + line); //Вывести введённые данные

            bufferedReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Закрытие потока

Мы всегда должны использовать метод close() класса BufferedReader, чтобы освободить все системные ресурсы, связанные с читателем. Чтобы упростить код, мы можем использовать блок try-with-resources, чтобы автоматически закрыть поток.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderDemo {
    public static void main(String[] args) {
        String path = "path/to/your/file.txt";
        try (FileReader fileReader = new FileReader(path);
             BufferedReader bufferedReader = new BufferedReader(fileReader)) {

            // Добавьте код для чтения данных из файла здесь

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

BufferedReader против Scanner

И Scanner, и BufferedReader можно использовать для чтения данных из внешних источников. Однако между этими двумя классами есть некоторые различия. В этом шаге мы сравним некоторые ключевые различия.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;

public class BufferedReaderDemo {
    public static void main(String[] args) {
        String path = "path/to/your/file.txt";
        try (FileReader fileReader = new FileReader(path);
             BufferedReader bufferedReader = new BufferedReader(fileReader);
             Scanner scanner = new Scanner(fileReader)) {
            long startTime = System.nanoTime();
            // Чтение файла с использованием BufferedReader
            bufferedReader.readLine();
            while (bufferedReader.readLine()!= null) ;
            long endTime = System.nanoTime();
            System.out.println("Time taken by BufferedReader : " + (endTime - startTime) + "ns");

            startTime = System.nanoTime();
            // Чтение файла с использованием Scanner
            scanner.nextLine();
            while (scanner.hasNextLine()) scanner.nextLine();
            endTime = System.nanoTime();
            System.out.println("Time taken by Scanner : " + (endTime - startTime) + "ns");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Этот код сравнивает время, затрачиваемое BufferedReader и Scanner на чтение данных из одного и того же файла. Временные показатели могут различаться, но вывод покажет, какой из них занял больше времени.

Чтение файла построчно

Класс BufferedReader предоставляет несколько методов для чтения данных. Метод readLine() читает одну строку за раз. Этот метод возвращает null, если мы достигли конца потока. В этом шаге мы будем читать файл с использованием BufferedReader.readLine().

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderDemo {
    public static void main(String[] args) {
        String path = "path/to/your/file.txt";
        try (FileReader fileReader = new FileReader(path);
             BufferedReader bufferedReader = new BufferedReader(fileReader)) {

            String line;
            while ((line = bufferedReader.readLine())!= null) {
                System.out.println(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Чтение отдельных символов из файла

Мы также можем читать по одному символу за раз, используя метод read() класса BufferedReader. Этот метод возвращает прочитанный символ в виде целого числа. Если мы достигнем конца потока, то он вернёт -1.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderDemo {
    public static void main(String[] args) {
        String path = "path/to/your/file.txt";
        try (FileReader fileReader = new FileReader(path);
             BufferedReader bufferedReader = new BufferedReader(fileReader)) {

            int charRead;
            while ((charRead = bufferedReader.read())!= -1) {
                System.out.print((char) charRead);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Чтение нескольких символов из файла

Метод read() может читать несколько символов за раз. Мы должны передать массив символов, в котором будут храниться данные. Также нам нужно использовать смещение, которое указывает начальный индекс массива символов. Сохранённые данные начинаются с этого индекса. Также нужно указать максимальную длину символов для чтения.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderDemo {
    public static void main(String[] args) {
        String path = "path/to/your/file.txt";
        try (FileReader fileReader = new FileReader(path);
             BufferedReader bufferedReader = new BufferedReader(fileReader)) {

            char[] charArr = new char[5];
            bufferedReader.read(charArr, 0, 5);
            System.out.print(charArr);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Пропуск символов

Класс BufferedReader предоставляет метод skip(), который мы можем использовать для пропуска символов. Он принимает параметр типа long.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderDemo {
    public static void main(String[] args) {
        String path = "path/to/your/file.txt";
        try (FileReader fileReader = new FileReader(path);
             BufferedReader bufferedReader = new BufferedReader(fileReader)) {

            int charRead;
            StringBuilder sb = new StringBuilder();
            while ((charRead = bufferedReader.read())!= -1) {
                if (charRead!= '*') {
                    sb.append((char) charRead);
                } else {
                    bufferedReader.skip(1);
                }
            }
            System.out.println(sb);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Маркирование и сброс

Класс BufferedReader предоставляет нам метод mark(), чтобы пометить определённый символ. Мы можем вернуться к этому помеченному символу в любое время в будущем, используя метод reset(). Метод mark() принимает целое число в качестве входных данных, которое обозначает максимальное количество байт, которое можно прочитать, прежде чем метка станет недействительной.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderDemo {
    public static void main(String[] args) {
        String path = "path/to/your/file.txt";
        try (FileReader fileReader = new FileReader(path);
             BufferedReader bufferedReader = new BufferedReader(fileReader)) {

            char[] charArr = new char[5];
            charArr[0] = (char) bufferedReader.read();
            charArr[1] = (char) bufferedReader.read();

            bufferedReader.mark(10);
            bufferedReader.skip(1);
            charArr[2] = (char) bufferedReader.read();
            charArr[3] = (char) bufferedReader.read();
            charArr[4] = (char) bufferedReader.read();
            System.out.println(charArr);

            bufferedReader.reset();
            char asterisk = (char) bufferedReader.read();
            System.out.print(asterisk);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Резюме

В этом практическом занятии мы использовали класс Java BufferedReader для чтения текста из символьного входного потока. Мы узнали, как обернуть другие классы читателей и входные потоки с использованием BufferedReader, чтобы повысить производительность и эффективность. Мы рассмотрели такие темы, как чтение отдельных и нескольких символов из файла, пропуск символов, маркирование и сброс позиций в файле, а также сравнение классов BufferedReader и Scanner. Мы также использовали блоки try-with-resources для автоматического закрытия потока и избежания утечек памяти.