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




В зависимости от типа/содержимого файла вы можете загрузить его в таблицу базы данных и выполнить анализ с помощью запросов к нему (например, если это был файл .csv).
Это широкая тема, но обычно такие проблемы решаются с помощью буфера.
Размер буфера - это то, что может хранить ваша память, и вы можете читать данные из файла и загружать их в буфер для выполнения задачи, а затем очищать буфер и загружать следующий фрагмент и так далее.
Например, если вы хотите отсортировать некоторые данные, которые слишком велики для памяти, мы используем метод, известный как внешняя сортировка.
В основном реляционная база данных использует этот метод внешней сортировки для сортировки данных, когда мы используем предложение Сортировать по в нашем запросе. Для более подробной информации об этом есть замечательная лекция, ссылка на видео которой вставлена ниже.
https://thewikihow.com/video_YjFI9CJy6x0&t=3506s
Я надеюсь, что это поможет вам в понимании.
Я ищу код Java для реализации этого.
вы можете обратиться к stackoverflow.com/questions/8402106/…
Я бы ответил: «Это зависит». В сценарии интервью они, вероятно, намеренно задают вам расплывчатый вопрос, чтобы увидеть, что вы с ним сделаете. Как отмечают другие, поиск информации о файле и о том, какую информацию вы хотите из него получить, является ключевым, и возможные решения могут сильно различаться в зависимости от этих факторов.
Например, если файл на самом деле CSV, и вы хотите выполнить потенциально сложный анализ данных (сортировка, подсчет, агрегирование и т. д.), то размещение его в таблице реляционной базы данных, скажем, H2, может быть неплохой идеей. . Если файл содержит больше текста в произвольной форме, вы можете проиндексировать его с помощью Lucene или поместить его в индекс ElasticSearch, а затем просмотреть его с помощью Kibana.
Однако ни одно из этих решений не анализирует файл «с кодом» и было бы совершенно неэффективным, если бы файл был, скажем, видеоклипом размером 100 ГБ. Поскольку они спрашивают, как вы будете анализировать файл «с кодом», я ожидаю, что они попытаются выяснить, знаете ли вы, как выполнять байт-ориентированный ввод-вывод (например, Java InputStream) по сравнению с символьно-ориентированным (например, Reader) и /или как прочитать потенциально большой файл с использованием буфера (т.е. без загрузки всего файла в память).
Вот простой пример кода...
import java.io.*;
public class StreamFile {
/** Stream through a file using a buffer. */
final static int BUFSIZE = 1024; // Use a 1K buffer.
public static void main(String[] args) throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(args[0])));
long totalBytes = 0;
byte[] buf = new byte[BUFSIZE];
while (bis.available() > 0) {
totalBytes += bis.read(buf, 0, BUFSIZE); // Do something here with the data in buf.
System.out.println(totalBytes); // Show progress.
}
System.out.println("Read " + totalBytes + " bytes");
bis.close();
}
}
Точно. Я думаю, что вы попали в точку с I expect they're trying to see if you know how to do byte-oriented I/O (e.g. Java InputStream) vs character-oriented (e.g. Reader) and/or how to read through a potentially large file using a buffer (i.e. without loading the whole file into memory). Я имею в виду, как я могу это сделать? Если, по крайней мере, вы можете указать мне точное ключевое слово, чтобы я мог гуглить или что-то в этом роде? Какой буфер? я был бы очень благодарен
Я добавил ссылку на пример кода. Я не проводил исчерпывающий поиск, чтобы найти лучший, но общая идея состоит в том, чтобы либо читать файл по одному байту за раз (до EOF), либо до определенного количества байтов в байтовый буфер (до EOF) . Вы можете использовать Reader, если знаете, что файл состоит из символов, в противном случае вам нужно использовать Steams. Учебник по Java с сайта Oracle очень хорош. В противном случае найдите что-то вроде «файл потока буфера java» и т. д.
Я думаю, что эта статья прекрасно резюмирует это, несовместимо с тем, что вы предложили. Хотелось бы получить ваши отзывы об этой короткой, но четкой статье. baeldung.com/java-read-lines-large-file
Конечно, статья довольно хорошая, но у нее есть пара вопросов для ваших целей. Во-первых, он демонстрирует использование сторонних пакетов (например, Guava и Apache Commons), что может быть нормально, если вы уже используете эти пакеты, но может не помочь, если вы пытаетесь изучить основную концепцию (например, как прочитать файл с использованием буфера). Кроме того, он привносит в картину управление зависимостями и потенциально временное управление зависимостями (т. е. как я могу получить эти банки и, возможно, любые банки, от которых зависят эти банки, в мой ПУТЬ К КЛАССУ). Возможно, лучше придерживаться простого JDK.
Во-вторых (не хватило места в комментарии;), простой пример Java предполагает, что файл содержит символы (а не байты, которые могут или не могут отображаться в символы), а также что одна строка помещается в память (т.е. файл может быть 100 ГБ и не содержат новых строк).
Да, ты прав. Это имеет смысл. Я думаю, что мне придется копать немного больше, но я получил основную идею. Необходимо использовать Input streams для чтения данных из буфера, если файл не содержит символов, и чтения побайтно, а не для загрузки всего файла в память. В противном случае используйте Buffered Reader , если он содержит символы. Спасибо за помощь. Очень ценю !
Я попробовал пример кода для чтения файла размером 10 ГБ. Если я использую BufferedReader, я получаю исключение из памяти, но при использовании BufferedInputStream кажется, что он работает отлично. Как вы сказали, я читал еще, что если файл содержит обычный текст, мы должны использовать BufferedReader. Но, похоже, это не работает. Есть идеи ?
Я заменил ссылку на пример небольшой программой, которая, я надеюсь, кратко демонстрирует потоковую передачу. Это должно иметь возможность передавать через действительно большой файл до переполнения «totalBytes». Трудно сказать, почему у вас не хватает памяти при использовании Reader, не видя кода. Одной из распространенных ошибок может быть использование readLine() для двоичного файла, в котором нет строк, что может привести к считыванию всего файла в память.
Это слишком широко - если бы мне задали этот вопрос в интервью, я бы спросил "что за файл, какой анализ?"