Советы по собеседованию по потоку ввода-вывода Java
Советы по собеседованию по потоку ввода-вывода Java

Вроде сначала, а потом читай, Java продвинута более чем наполовину.

Брат Нэн находится за границей stackoverflow смотретьприезжать13Такой вопрос многолетней давности:Как использовать Java построчночитать большой текстовый файл。У вас есть идеи??Давайте обсудим вместе в комментариях。

I need to read a large text file of around 5-6 GB line by line using Java.

How can I do this quickly?

Ответ, получивший больше всего голосов, дал парень по имени Питер Лоури.

Меня зовут брат Нэн, я думаю, вам будет полезно пройти собеседование и получить предложение.

Постучите по доске: в этой статье кратко описывается Java. Поток ввода-вывода, Java Общие вопросы на собеседовании NIO!=

1. Поток ввода-вывода

1.1 Понимание ввода-вывода

Интервьюер: Можете ли вы рассказать мне, как вы понимаете Java IO?

Java I/O имеет два участвующих объекта,одинКонец источника ввода/вывода,одинхочуиI/OРазличные типы исходной связипринимающая сторона,Например, программа управляет выводом консоли IDEA, записывает файл А в файл Б и т.д.,Наша программа хочет гарантировать, чтоIOТечь плавночитатьи пиши спокойно。JDKПолучите это правильноJava IOВся поддержка заложенаpackage java.ioБао Ся,Брат Нэн посчитал,Один имеет 86 классов и интерфейсов.

Давайте посмотримpackage java.ioНаиболее часто используемые пакетыReaderиWriterинтерфейс,он Все их авторыMark Reinhold。Кто этот парень??ондаOracle Главный архитектор группы платформ Java и ведущий инженер по средствам чтения и записи символьного потока. На таком фоне кажется, что Java Программирование ввода-вывода — дело непростое, и мы можем извлечь из него много полезного.

Язык кода:java
копировать
/** 
 * @author      Mark Reinhold
 * @since       JDK1.1
 */
public abstract class Reader implements Readable, Closeable { }
public abstract class Writer implements Appendable, Closeable, Flushable { }

1.2 Абстрактный базовый класс входного потока байтов

Интервьюер: Как прочитать поток байтов?

Давайте сначала поговорим о входном потоке, а затем о выходном потоке. Входной поток делится на поток байтов и поток символов. Как следует из названия, поток байтов считывается в байтах, а единица данных операции — 8-битные байты, а поток символов считывается в символах; единицей данных операции являются 16-битные символы.

читатьбайтабстрактный базовый классдаInputStream,Этот базовый класс предоставляет нам 3 метода для потоковой передачи потоков байтов.

(1) Читается следующий байт данных из входного потока.,Байт значения начинается с0приезжать255в пределах досягаемостиintвозвращаться。

Язык кода:java
копировать
public abstract int read() throws IOException

(2)из входного потокачитатьопределенная суммабайти хранить ихприезжатьбуфермножествоbсередина。

Язык кода:java
копировать
public int read(byte b[]) throws IOException

(3)из входного потокачитатьбольшинствоlenиндивидуальныйбайтданныеприезжатьбайтмножествосередина。

Язык кода:java
копировать
public int read(byte b[], int off, int len) throws IOException

Обратите внимание, что все возвращаемые параметры вышеуказанных методов имеют типы int.,Когда нормально читать,intвозвращатьсяиздачитать Количество байтов;И когдаintВозврат -1,Это указывает на то, что входной поток достиг конца.

1.3 Чтение входного потока байтов

Интервьюер: Это не примеры. Я хочу, чтобы это действительно можно было прочитать?

Вышеупомянутый абстрактный интерфейс,Сам по себе он не имеет реальной функции。действительно способныйчитатьдокументиздаInputStreamРеализация подкласса абстрактного базового класса,НапримерФайловый потокFileInputStream,С он,Читаем аудио, видео, gif и т. д. не являются проблемой.

Язык кода:java
копировать
// поток файловчитать файл
FileInputStream stream = new FileInputStream(SOURCE_PATH);

нас Достаточно хорошосуществовать Добавьте слой снаружипоток байтов кэшаулучшитьчитатьэффективность,Поместите объект BufferedInputStream во внешний слой.,О том, почему эффективность чтения можно повысить, я расскажу ниже.

Язык кода:java
копировать
BufferedInputStream stream = new BufferedInputStream(new FileInputStream(SOURCE_PATH));

В приведенном выше потоке байтов мы используем n байтов для чтения.,Если вы хотите использоватьreadLine()читать Определенная строка неприменима в этом сценарии.。насмогу поставитьпоток байтов кэша Заменить накэшировать поток символовпредпринять,использоватьInputStreamReaderПроцесс конверсииПучокбайтвходной потокизменять Заменить нахарактервходной поток。

Как показано в следующем коде.

Язык кода:java
копировать
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(SOURCE_PATH)));

1.4. Повышение эффективности чтения

Интервьюер: Почему добавление уровня потока кэша может повысить эффективность чтения?

Почему добавление уровня потока кэша может повысить эффективность чтения? Потому что он используется напрямую FileInputStream Чтобы прочитать файл, каждый раз вызывайте read() ВседаотДиск читает один байт,И каждый разчитать Вседасистемный вызов。Системные вызовы — это вызовы на уровне операционной системы.,Включает переключение контекста между пространством пользователя и пространством ядра.,Эти переключатели дорогие.

А если вы используете поток кэша, из файла в кэш одновременно считывается несколько байтов, что уменьшает системные вызовы и операции чтения с диска, а эффективность чтения значительно повышается.

Кроме Java Ввод-вывод использует кэшированные потоки для повышения эффективности чтения. Большинство приложений также используют кэширование для повышения производительности программы, например наше. частьсуществоватьвстреча по развитию бизнесаиспользоватьRedisКэш в будущемуменьшать Давление на базу данных。оЗачем использовать кэширование для повышения эффективности приложений,Вы также можете посмотреть за рубежомQuoraотвечать,Очень подробное объяснение.

1.5 Поток ввода символов

Интервьюер: А как насчет чтения потока символов?

характервходной потокабстрактный базовый классдаReader,Он также предоставляет 3 метода для поддержки потока чтения.

(1) Прочитайте один символ.

Язык кода:java
копировать
public int read() throws IOException

(2) Считайте символы в массив.

Язык кода:java
копировать
public int read(char cbuf[]) throws IOException

(3) Считайте символы в часть массива.

Язык кода:java
копировать
abstract public int read(char cbuf[], int off, int len) throws IOException

характерпотокчитатьиз实例даFileReader,То же самое можно сделатьиспользоватькэшировать поток символы повышают эффективность чтения.

Язык кода:java
копировать
BufferedReader reader = new BufferedReader(new FileReader(new File(SOURCE_PATH)));

Давайте сделаем это подробно,читатьC:\\Users\\Desktop\\JavaProGuide\\readВсе файлы под,Объедините их вместе,писатьприезжатьC:\\Users\\Desktop\\JavaProGuide\\writeвнизPRODUCT.txtдокументсередина。

Язык кода:java
копировать
public class Client {

    private static final String PATH = "C:\\Users\\Desktop\\JavaProGuide\\read";

    private static final String FILE_OUT = "C:\\Users\\Desktop\\JavaProGuide\\write\\PRODUCT.txt";

    public static void main(String[] args) throws IOException {
        File file = new File(PATH);
        File[] files = file.listFiles();

        BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_OUT));

        for (File curFile : files) {
            BufferedReader reader = new BufferedReader(new FileReader(curFile));
            String line;
            while ((line = reader.readLine()) != null) {
                writer.write(line);
                writer.newLine();
            }
            reader.close();
        }

        writer.close();
    }

}

1.6 Выходной поток

Интервьюер: Можете ли вы также рассказать о выходном потоке?

байтвыходной потокабстрактный базовый классдаOutputStream,характервыходной потокабстрактный базовый классдаWriter。он Они предоставляют следующие методы соответственно。

байтвыходной потокOutputStream

(1) Запишите указанные байты в этот выходной поток.

Язык кода:java
копировать
public abstract void write(int b) throws IOException

(2)уточнитбайтмножествосерединаизb.lengthбайтписатьэтотвыходной поток。

Язык кода:java
копировать
public void write(byte b[]) throws IOException 

(3)уточнитбайтмножествосерединаот偏移量offначалосьlenиндивидуальныйбайтписатьэтотвыходной поток。

Язык кода:java
копировать
public void write(byte b[], int off, int len) throws IOException

характервыходной потокWriter

(1) Напишите один символ.

Язык кода:java
копировать
public void write(int c) throws IOException

(2) Записать массив символов.

Язык кода:java
копировать
public void write(char cbuf[]) throws IOException

(3) Запишите часть массива символов.

Язык кода:java
копировать
abstract public void write(char cbuf[], int off, int len) throws IOException

кроме тогохарактервыходной потокдаиспользоватьхарактерманипулировать данными,Так что его можно использоватьхарактер Вместо этого строкахарактермножество,JDKТакже поддерживает следующиеВходдахарактерстроковый метод。

(1) Напишите строку.

Язык кода:java
копировать
public void write(String str) throws IOException

(2) Запишите часть строки.

Язык кода:java
копировать
public void write(String str, int off, int len) throws IOException

1.7 Различия между потоком байтов и потоком символов

Интервьюер: В чем разница между потоком байтов и потоком символов?

Разница между потоком байтов и потоком символов в основном заключается в трех аспектах.

  • Базовые единицы разные.。байтпотоккбайт(8бит двоичного числа)Обработка данных в базовых единицах,Потоки характера обрабатывают данные в единицах характера.
  • Различные сценарии использования。байтпоток操作可к所有类型данные,Включает текстовые данные,инетекстовые данныеКак изображение、Аудио и т. д., тогда как поток характера подходит только для обработки текстовых данных.
  • Что касается производительности。потому чтобайтпоток Не обработанохарактеркодирование,Поэтому при работе с большими объемами текстовых данных это может быть не так хорошо, какхарактерпоток Эффективный;ихарактерпотокиспользоватьприезжатьбуфер памятиОбработка текстовых данных оптимизирует операции чтения и записи.。

2. Java NIO

2.1 Введение в NIO

NIOВнешний вид заключается в улучшенииIOскорость,он сравниваеттрадиционный вход/выходной поток Быстрее。NIOчерез трубыChannelибуферBufferобрабатывать данные,Думайте о трубопроводе как о шахте,Буфер — это грузовик в шахте.

Программа обменивается данными через буфер в конвейере.,иНе обрабатывает данные напрямую。Программа либо получает данные из буфера,Либо вводите данные в буфер.

2.2 Каналы и буферы

NIO предоставляет два основных объекта: каналы и буферы.

(1)трубопроводChannel

с традиционнымIOпоток只能只读或只写изОдносторонний потокдругой,NIOряддадвусторонний,Другими словами, операции чтения и записи могут выполняться одновременно.,Это делает обработку данных более эффективной.

(2)буферBuffer

Традиционные потоки ввода-вывода обрабатывают только один байт за раз, и каждый прочитанный байт представляет собой системный вызов, включающий переключение контекста между пространством пользователя и пространством ядра, что, как правило, неэффективно.

иNIOИспользуйте файлы, отображаемые в памяти, для обработки ввода/выход,Channelпроходитьmap()методфрагмент данныхкартографированиеприезжать Памятьсередина。программапроходитьBufferВыполнение взаимодействия с данными,уменьшать Прямой доступ к исходным источникам данных。NIOблочно-ориентированныйиз处理方式使得эффективностьвыше。

2.3 Неблокирующая модель ввода-вывода

традиционный вход/выходной потокдасинхронная блокировкаIOМодель,Если в источнике данных нет данных,На этом этапе программа заблокируется.

иNIOдаI/OМультиплексирование Модель,Потоки могутпроситьЕсть ли на канале доступные данные?,Нет необходимости блокировать поток, когда нет данных.

2.4 Обрабатывает ли поток символов символы?

Все данные Включает текстовые данные最终ВседакБайтовая формахранится,Потому что нижний уровень компьютера может понимать только двоичные данные.

Символы в конечном итоге должны быть преобразованы в байтовую форму. Причина, по которой вы можете видеть символы в текстовых файлах, заключается в том, что система преобразует базовую двоичную последовательность в символы.

2.5 Buffer

BufferЕсть3индивидуальныйключевые переменные

  1. capcity:выражатьбуферBufferМаксимальная емкость данных。
  2. position:Используется для указания следующегоиндивидуальный可к读出/писатьBufferиндексная позиция,Это роль указателя записи.
  3. limit:используется для выражения вBufferПервый в миреиндивидуальныйневозможно прочитать/писатьиндексная позиция。

кроме тогоBufferТакже предоставленоgetputметод предоставлениянас Данные операции,ииспользоватьget/putназад,Положение указателя положения также изменится соответствующим образом.

Язык кода:java
копировать
public abstract byte get();

public abstract ByteBuffer put(byte b);

2.6 Channel

Канал имеет три общих метода: map(), read() и write().

Язык кода:java
копировать
// Сопоставьте область файла канала непосредственно с байтовым буфером.
public abstract MappedByteBuffer map(MapMode mode, long position, long size)

// Последовательность байтов из этого канала в данный буфер dst
public abstract int read(ByteBuffer dst)
    
// Записывает последовательность байтов из src в данном буфере в этот канал.
public abstract int write(ByteBuffer src)

к下даChannelиз简单использоватькод。

Язык кода:java
копировать
public class TestFileChannel {
    public static void main(String[] args) {
        File f = new File("D:\\JavaGetOffer\\TestFileChannel.java");
        try {
            FileChannel inChannel = new FileInputStream(f).getChannel();
            FileChannel outChannel = new FileOutputStream("a.txt").getChannel();
            MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, f.length());

            outChannel.write(buffer);
            buffer.clear();
            CharBuffer charBuffer = StandardCharsets.UTF_8.newDecoder().decode(buffer);
            System.out.println(charBuffer);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

2.7 Нулевая копия NIO

существоватьNIOДо нулевой копии,одининдивидуальныйI/OОперация будет выполнена с теми же данныминесколько копий。Вы можете увидеть картинку ниже,Операция ввода-вывода выполняет четыре операции над данными.,Поставляется с двумя переключателями контекста: Режим ядра и Пользовательский режим одновременно.,Хорошо известно, что переключение контекста — очень ресурсозатратная операция.

Технология нулевого копирования решает вышеупомянутые проблемы. Вы можете сравнить картинку ниже,Технология нулевого копированияуменьшатьКоличество копий фрагмента данных,Больше не нужно передавать данныесуществоватьРежим ядра и пользовательский режимкопировать между,Это также означает отсутствие переключения контекста.,Сделайте передачу данных более эффективной.

Я Брат Нэн, Нэн - это Нэн. Мне нравятся ваши лайки, лайки и лайки на Get.

Творить непросто, поэтому вы можете ставить лайки, собирать и подписываться, чтобы поддержать его. Ваша поддержка — самая большая мотивация для моего творчества.❤️

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose