Лучший способ прочитать огромный файл (например, очень большой текстовый документ)

Я новичок в Java ... в моем текущем проекте мне нужно прочитать и написать очень большой текстовый файл (1 ГБ - 5 ГБ)... сначала я использовал следующие классы: BufferedReader и BufferedWriter

public static String read(String dir) {
    BufferedReader br;
    String result = "", line;
    try {
        br = new BufferedReader(new InputStreamReader(new FileInputStream(dir), "UTF-8"));
        while ((line = br.readLine()) != null) {
            result += line + "\n";
        }
    } catch (IOException ex) {
        //do something
    }
    return result;
}

public static void write(String dir, String text) {
    BufferedWriter bw;
    try {
        bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dir), "UTF-8"));
        bw.write("");
        for (int i = 0; i < text.length(); i++) {
            if (text.charAt(i) != '\n') {
                bw.append(text.charAt(i));
            } else {
                bw.newLine();
            }
        }
        bw.flush();
    } catch (IOException ex) {
        //do something
    }
}

этот класс работает очень хорошо, но не для огромных файлов...

Затем я использовал MappedByteBuffer для read() метод (я не знаю, как написать файл, используя этот класс):

public static String read(String dir) {
    FileChannel fc;
    String s = "";
    try {
        fc = new RandomAccessFile(dir, "r").getChannel();
        MappedByteBuffer buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
        buffer.load();
        buffer.force();
        for (int i = 0; i < buffer.limit(); i++) {
            s += (char) buffer.get();
        } //I know the problem is here
        buffer.clear();
        inChannel.close();
    } catch (IOException e) {
        //do something
    }
    return s;
}

Но по-прежнему не может читать большие файлы (более 30-40 МБ), даже Блокнот работает быстрее, чем мое приложение:))

а также еще одна проблема, я не знаю, как изменить кодировку вторым способом (например, "UTF-8", "ANSI",...)

ребята, скажите, пожалуйста, как лучше всего читать и записывать файлы laaaarge? любая идея?

5 ответов

Решение

По крайней мере, я бы рекомендовал изменить

result += line + "\n";

к StringBuilder.

resultBldr.append(line).append("\n");

Это позволяет избежать создания нового строкового объекта - большего и большего, большего и большего строкового объекта!- в каждой строке.

Кроме того, вы должны обязательно записать свой вывод в файл построчно. Не накапливайте весь этот текст, а затем выводите его.

Другими словами, в этой ситуации полное разделение между вашими read а также write функции не рекомендуется.

result += line + "\n";

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

while ((line = br.readLine()) != null) {
            processLine( line ); // this may write it to another file.
        }

Всегда плохо читать файлы большого размера в диапазоне от 1 ГБ до 5 ГБ за один раз. Будет огромная производительность, и ваше приложение будет замедляться.

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

Вы слышали о системе HDFS, индексации Solr, платформах Apache Hadoop, которые специально предназначены для работы с большими данными. Возможно, вы захотите взглянуть на это.

Подумайте, что каждое связывание строк создает новую строку, поэтому, если вы читаете каждый символ большого файла размером 40 МБ и объединяете, вы создаете в общей сложности 40 000 000 строк в read(),

Попробуй использовать StringBuffer вместо String Рекомендую для этой ситуации.

Лучше использовать класс Scanner, поскольку он использует поток, и попытаться отправить содержимое в БД, поскольку БД может хранить больше данных, чтобы вы могли выполнять с данными что угодно. для чтения данных используйте запрос с ограничением FETCH. Я использовал это для файла размером 3 ГБ, и он работает без каких-либо проблем.

Другие вопросы по тегам