Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Как прочитать большой файл? / 22 сообщений из 22, страница 1 из 1
16.07.2017, 08:46
    #39489648
azsx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
Вопрос: как в java прочитать в переменную большой файл? Или что я делаю не так?
Вот код
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
InputStreamReader isr =
            new InputStreamReader( new FileInputStream( fileName ),
                                   charset );
        BufferedReader buff = new BufferedReader( isr );
        StringBuffer strBuff = new StringBuffer();
int c_count = 0;
        int c;

        while ( ( c = buff.read() ) != -1 ) {
            strBuff.append( ( char )c );
            c_count = c_count + 1;
            if ((c_count % 1000) == 0) {
                System.out.println(c_count);
            }
        }

        return strBuff.toString();
}   



Код: java
1.
2.
3.
Read_Log read_log = new Read_Log();
String str_log = "";
str_log = read_log.openFileAsString("moi_file.log", "CP866");


По какой то загадочной для меня причине при достижении c_count = 37_748_000 программа вылетает по ошибке:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:3332)
	at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
	at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:649)
	at java.lang.StringBuffer.append(StringBuffer.java:381)
	at ago.Read_Log.openFileAsString(Read_Log.java:77)
	at ago.fmain.jButton2ActionPerformed(fmain.java:176)
	at ago.fmain.access$100(fmain.java:16)
	at ago.fmain$3.actionPerformed(fmain.java:78)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
	at java.awt.Component.processMouseEvent(Component.java:6533)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
	at java.awt.Component.processEvent(Component.java:6298)
	at java.awt.Container.processEvent(Container.java:2236)
	at java.awt.Component.dispatchEventImpl(Component.java:4889)
	at java.awt.Container.dispatchEventImpl(Container.java:2294)
	at java.awt.Component.dispatchEvent(Component.java:4711)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
	at java.awt.Container.dispatchEventImpl(Container.java:2280)
	at java.awt.Window.dispatchEventImpl(Window.java:2746)
	at java.awt.Component.dispatchEvent(Component.java:4711)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)


Read_Log.java:77 это
Код: java
1.
strBuff.append( ( char )c );


Пробовал в netbeans: Выполнить, конфигурация проекта, настроить, аргументы -- ставить разные аргументы до -Xmx4000m -Xms2000m не помогает совсем никак. Я хочу прочитать файл 61 мБ, но мне надо будет читать до нескольких сотен мБ.
Что не так?
...
Рейтинг: 0 / 0
16.07.2017, 11:38
    #39489665
marcoman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
Код: java
1.
2.
3.
4.
5.
6.
7.
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

Path path = Paths.get("file-size-is-100MB.data");
byte[] fileData = Files.readAllBytes(path);
System.out.println(fileData.length);



azsxкак в java прочитать в переменную большой файл?Зачем?
...
Рейтинг: 0 / 0
16.07.2017, 11:43
    #39489666
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
Пока - непонятно. Но код изначально имеет code smells.

У тебя - кмк путаница с использованием API для чтения файлов.

- Почему объявлен целый стек текстового API InputStreamReader -> BufferedReader но
при этом ты читаешь 1 символ? Читай блоками фиксированной длины или строками (до символа перевода строки).

- Почему используется StringBuffer? Он - для мультипоточности. Используй StringBuilder.

- В Apache commons IO есть готовые API для прочтения текстового файла в строку. Если для
тебя это не предмет изучения а просто нужно - то используй его.
...
Рейтинг: 0 / 0
16.07.2017, 11:44
    #39489667
Usman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
...
Рейтинг: 0 / 0
16.07.2017, 11:49
    #39489669
Dmitry.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
в коде ничего предосудительного не вижу за исключением, что чтение ведется посимвольно.

для сравнения: код наиболее используемой библиотеки для таких задач - org.apache.commons.io.IOUtils

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    public static long copyLarge(Reader input, Writer output) throws IOException {
        char[] buffer = new char[DEFAULT_BUFFER_SIZE];
        long count = 0;
        int n = 0;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
            count += n;
        }
        return count;
    }




скорее всего ты где-то не там ставишь настройки памяти...

для информации:
ты читаешь свой файл в одно-байтовой кодировке (cp866)
т.е. каждый байт из файла представлен в памяти в виде одного char = 2 байта
StringBuffer при нехватке размера внутреннего буфера создает его копию двойного размера что приводит в худшем случае к тройному использованию памяти.

OutOfMemory у тебя выпадает на 37_748_000 символах
x 2 = 75_496_000 байт
x 3 = 226_488_000 байт

что очень близко к дефолтному пределу памяти

можно StringBuilder создавать по размеру файла тогда не будет х3 использования памяти при чтении
но во время StringBuilder.toString() будет x2

а лучше избежать чтения всего файла в память...
...
Рейтинг: 0 / 0
16.07.2017, 12:19
    #39489675
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
azsx,

Не используйте String для таких объемов. Вам всё равно такая огромная строка целиком не нужна. Особенно в Java 8, где один char это гарантировано 2 байта.
Большие файлы нужно парсить прямо во время чтения. Вам нужен Reader или Scanner, или оба, чтобы при чтении разбивать и складывать в структуру оптимизированную для представления. Правда, тут хитрый вопрос. В Java 8 лучше держать данные в byte[], а в String конвертировать только во время представления на UI. А вот для Java 9 можно смело держать всё в String-ах. Если все символы умещаются в байты, то String будет держать только byte[].

Если задача только парсить, то блин, вообще не надо хранить всё в памяти. Читайте построчно и анализируйте.
...
Рейтинг: 0 / 0
16.07.2017, 12:21
    #39489676
Partisan M
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
azsxкак в java прочитать в переменную большой файл?

У вас маленький файл.

azsxИли что я делаю не так?

Вот что:

Код: java
1.
strBuff.append( ( char )c );



Накапливаются удалённые, но не вычищенные из памяти объекты. На это намекает сообщение java.lang.OutOfMemoryError: Java heap space. Каждый раз, когда StringBuffer увеличивается сверх текущей ёмкости, удаляется массив char[], в котором фактически хранятся его данные (сначала они копируются в новый массив, созданный для этого StringBuffer). Поскольку вы увеличиваете StringBuffer на 1 символ, то удалений прежних массивов будет много. Во избежание этого можно с самого начала закрепить за StringBuffer большую ёмкость: new StringBuffer (ёмкость) и потом увеличивать его больше, чем на один символ - добавлять в него не символ, а целую строку или применять StringBuffer.ensureCapacity (желаемая ёмкость).
...
Рейтинг: 0 / 0
16.07.2017, 12:33
    #39489683
azsx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
marcoman попробовал Вашим методом, теперь памяти не хватает на строке
Код: java
1.
String vernut = new String(fileData, "CP866");



Код: java
1.
2.
3.
4.
5.
6.
7.
    String all_err_log2(String fileName) throws IOException {
        Path path = Paths.get(fileName);
        byte[] fileData = Files.readAllBytes(path);
        System.out.println(fileData.length);
        String vernut = new String(fileData, "CP866");
        return vernut;
    }



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
	run:
64105439
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
	at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:149)
	at java.lang.StringCoding.decode(StringCoding.java:193)
	at java.lang.String.<init>(String.java:426)
	at java.lang.String.<init>(String.java:491)
	at ago.Read_Log.all_err_log2(Read_Log.java:94)
	at ago.fmain.jButton2ActionPerformed(fmain.java:177)
	at ago.fmain.access$100(fmain.java:16)
	at ago.fmain$3.actionPerformed(fmain.java:78)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
	at java.awt.Component.processMouseEvent(Component.java:6533)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
	at java.awt.Component.processEvent(Component.java:6298)
	at java.awt.Container.processEvent(Container.java:2236)
	at java.awt.Component.dispatchEventImpl(Component.java:4889)
	at java.awt.Container.dispatchEventImpl(Container.java:2294)
	at java.awt.Component.dispatchEvent(Component.java:4711)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
	at java.awt.Container.dispatchEventImpl(Container.java:2280)
	at java.awt.Window.dispatchEventImpl(Window.java:2746)
	at java.awt.Component.dispatchEvent(Component.java:4711)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)


авторскорее всего ты где-то не там ставишь настройки памяти...
Скорее всего, не понимаю как их ставить там.

оффтопик
автор- Почему используется StringBuffer? Он - для мультипоточности. Используй StringBuilder.
как я понимаю надо рассчитывать, что когда нибудь я буду писать программы на java, а не утилиты. Один из серьёзных плюсов java над pascal -- это более понятная и удобная в реализации многопоточность. Мне уже сейчас надо 2 файла анализировать, можно одновременно.
...
Рейтинг: 0 / 0
16.07.2017, 12:35
    #39489685
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
azsx,

Вы бы параметры VM писали бы не в аргументы, а в параметры VM. Может тогда бы они и применились.
...
Рейтинг: 0 / 0
16.07.2017, 12:39
    #39489688
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
azsxкак я понимаю надо рассчитывать, что когда нибудь я буду писать программы на java, а не утилиты. Один из серьёзных плюсов java над pascal -- это более понятная и удобная в реализации многопоточность. Мне уже сейчас надо 2 файла анализировать, можно одновременно.
Вам не нужно загружать файл целиком в память, чтобы его проанализировать. Даже если файл имеет не потоковую структуру, то можно использовать RandomAccessFile. Но лог, он потоковый. Обычно, строго упорядочен по времени. Толку от того что он у вас целиком в памяти - ноль.
...
Рейтинг: 0 / 0
16.07.2017, 12:40
    #39489689
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
Да ему не нужно весь лог в строку прогружать. Все равно это - пол задачи.

Вот пускай автор расскажет что он дальше будет делать с этой толстой строкой.

А то накидают ему тут советов.... байты читать. Вообще не в тему.
...
Рейтинг: 0 / 0
16.07.2017, 12:44
    #39489690
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
maytonДа ему не нужно весь лог в строку прогружать. Все равно это - пол задачи.
Вот пускай автор расскажет что он дальше будет делать с этой толстой строкой.
А то накидают ему тут советов.... байты читать. Вообще не в тему.
Я было подумал, что он UI пишет для этого файла. Но теперь вижу что парсить собрался. Парсить лог файл вообще примитивная задача - читаем строками, анализируем регулярками. Можно даже через Java 8 Stream API.
https://www.mkyong.com/java8/java-8-stream-read-a-file-line-by-line/
...
Рейтинг: 0 / 0
16.07.2017, 13:00
    #39489696
azsx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
авторВы бы параметры VM писали бы не в аргументы, а в параметры VM.
Вот он ответ, огромное спасибо. Как я сам не подумал, что надо в vm писать. Плохо, что теперь gui приложение придётся не с одного jar файла запускать, а с sh, bat -- три файла. ээх...
авторВот пускай автор расскажет что он дальше будет делать с этой толстой строкой.
Образно, от программ идёт лог, где помимо всякой информации есть строки:
error-XXXX краткое, человеко понятное описание ошибки."\r\n"
По очень многим ошибкам можно отсылать майл юзеру автоматом
"Вы не прочитали инструкцию (текст инструкции), читайте внимательнее".
Я думаю, что буду читать эти файлы каждые 5 минут и посылать письма. Не понимаю, почем и что я делаю не так? Зачем мне постоянно держать эти файлы открытыми даже для чтения?
---
Накапливаются удалённые, но не вычищенные из памяти объекты.
Спасибо, учту, типа
StringBuffer strBuff = new StringBuffer(80000000);
оффтопик
авторНе используйте String для таких объемов. Вам всё равно такая огромная строка целиком не нужна.
Ну это я ваще не понимаю. У меня 6 гб оперативной, мне нужна эта строка для обработки, обработка посимвольно будет гораздо сложнее и запутанее.
...
Рейтинг: 0 / 0
16.07.2017, 13:00
    #39489697
azsx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
Кстати, пример с байтами мне показался более логичным для чтения файла. Это не так?
...
Рейтинг: 0 / 0
16.07.2017, 14:40
    #39489717
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
azsxОбразно, от программ идёт лог, где помимо всякой информации есть строки:
error-XXXX краткое, человеко понятное описание ошибки."\r\n"
По очень многим ошибкам можно отсылать майл юзеру автоматом
"Вы не прочитали инструкцию (текст инструкции), читайте внимательнее".
Я думаю, что буду читать эти файлы каждые 5 минут и посылать письма.1440 / 5 = 288 сообщений в сутки. Вас и проклянут и наплюют вам в карму.
Борьба с ошибками "нечитателей инструкции" - задача техподдержки.
Использовать для тривиальной задачи ваше странное поделие станут только совсем тупые неадекваты - есть тьма готовых инструментов, которым не требуется гигабайт памяти, чтобы найти строку в пару сотен байт.

P.S. Поскольку прозвучало "база данных" я уж совсем молчу про штатные варианты мониторинга ...
...
Рейтинг: 0 / 0
16.07.2017, 16:46
    #39489745
azsx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
1440 / 5 = 288 сообщений в сутки.
1. Много пользователей (больше сотни).
2. Только некоторые из этих ошибок требуют обращения к документации.
Сейчас в реальности юзер два три раза пытается сделать одно и то же, потом пишет в ТП и получает копипаст из документации.
авторБорьба с ошибками "нечитателей инструкции" - задача техподдержки.
Ага.
авторесть тьма готовых инструментов, которым не требуется гигабайт памяти, чтобы найти строку в пару сотен байт.
я знаю два, php и fpc. Вы знаете ещё? Как бы эту задачу решили Вы?
авторP.S. Поскольку прозвучало "база данных" я уж совсем молчу про штатные варианты мониторинга ...
Что не так?
...
Рейтинг: 0 / 0
16.07.2017, 17:49
    #39489759
azsx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
Кстати, не сразу понял. Я же не собираюсь каждые 5 минут одному и тому же пользователю слать документацию одинаковую. И конечно сперва потестю на тестовых ящиках.
В 61 мб, было 3600+ ошибок из них некоторые точно можно решить документацией.
Мне также интересно было число сколько ошибок всего, а то java логи пишет, кругом исключения, а кто их читает и вылизвыает -- непонятно.
...
Рейтинг: 0 / 0
16.07.2017, 17:54
    #39489763
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
azsxКстати, пример с байтами мне показался более логичным для чтения файла. Это не так?
Нет. Никогда так не делай. Байты - не для текстовых файлов. Вобщем огребешь
больше проблем чем профита.
...
Рейтинг: 0 / 0
16.07.2017, 18:00
    #39489767
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
azsx1440 / 5 = 288 сообщений в сутки.
1. Много пользователей (больше сотни).
2. Только некоторые из этих ошибок требуют обращения к документации.Это ещё не повод спамить пользователей (см.ниже).я знаю два, php и fpc. Вы знаете ещё?Это не инструменты - это пушки для стрельбы по воробьям.
Если "man tail" вам не нравится - попробуйте "man grep", "find /?", в конце концов.Как бы эту задачу решили Вы?Прежде чем бросаться на амбразуру, надо изучить врага проблему.
0. Отделить зёрна от плевел - не всё, что снабжено меткой ЕГГОГ действительно является ошибкой;
1. Понять, что на самом деле требуется - отсутствие ЕГГОГ-ов не может являться (само)целью;
"Так вот, чтобы всего этого достичь - надо учиться, учиться и учиться!" (ц) старый анекдот.
В вашем случае надо читать логи, пока вы не поймёте, что происходит в вашей системе и пока вам не станет ясно - что можно сделать с вашей стороны, а что придётся оставить как есть и с чем понадобиться бороться совершенно не техническими методами.
...
Рейтинг: 0 / 0
16.07.2017, 18:03
    #39489769
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
azsxМне также интересно было число сколько ошибок всего, а то java логи пишет, кругом исключения, а кто их читает и вылизвыает -- непонятно.Каждое исключение снабжено трассировкой стэка из которого вполне понятно - кто и где.
Почему, как правило, непонятно, но это уже другая история.
...
Рейтинг: 0 / 0
17.07.2017, 01:45
    #39489905
azsx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
авторВ вашем случае надо читать логи, пока вы не поймёте, что происходит в вашей системе
Тогда по сути я этим и займусь, просто максимально автоматизирую всё.
...
Рейтинг: 0 / 0
19.07.2017, 08:08
    #39491289
Andrew1411
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать большой файл?
Настроить логгер, что бы хотя бы ошибки отсаживать в отдельный файл, либо писать в БД ?
Написать свой аппендер, что бы он сразу занимался отправкой (надо всего лишь отнаследоваться от SMTP аппендера) ?

опять же, может достатьчно взять grep и sed, что бы не писать велосипед?

но и в любом случае, данные надо обрабатывать в поточном режиме, а не грузить все в память.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Как прочитать большой файл? / 22 сообщений из 22, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]