Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.68/76: Рейтинг темы: голосов - 76, средняя оценка - 4.68
7 / 7 / 2
Регистрация: 01.03.2013
Сообщений: 142

Наиболее эффективное чтение текстового файла

06.02.2015, 02:48. Показов 14445. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Как можно наиболее эффективно и быстро прочитать файл? Программа должна легко читать файл 5-10gb. В этом примере, я читаю файл и вывожу строку, которая содержит нужное слово:
Java
1
2
3
4
5
6
7
8
9
10
11
12
try(BufferedReader fileOut = new BufferedReader(new InputStreamReader(new FileInputStream(file))) ){
 
                for(String line; (line = fileOut.readLine()) != null; ){
                    if(line.contains(commandString)) 
                        System.out.println(count + ": " + line);
                    count++;
                }
 
                fileOut.close();
}catch(Exception e) {
            System.out.println(e);
        }
Но вот если в файле будет только одна строка и это большой файл, то программа упадёт. Как вы посоветуете читать файл? И искать слово в строке? Я думаю использовать посимвольный перебор или загружать файл по частям. Посоветуйте как лучше всего сделать.
1
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.02.2015, 02:48
Ответы с готовыми решениями:

Как заменить чтение строки из консоли на чтение текстового файла?
основное задание: найти частоту суффикса (например, "ing") в текстовом документе. в прикреплённом коде текст вводится прямо в консоль,...

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

Чтение текстового файла
Пробую читать текстовой файл. package javaapplication3; import java.io.*; import java.nio.channels.*; import java.nio.*; class...

11
Кандёхаем веселее!
 Аватар для MLPMan
296 / 330 / 76
Регистрация: 02.10.2012
Сообщений: 2,175
06.02.2015, 16:45
Была похожая тема недавно -> Запись и чтение большого файла или области на диске , посоветовали юзать БД.

Если в файле только одна строка, и разделить его (загружать по частям), будет риск разрезать искомое слово.
1
7 / 7 / 2
Регистрация: 01.03.2013
Сообщений: 142
06.02.2015, 17:56  [ТС]
MLPMan, спасибо за совет. Но мне не ясно, причем тут БД к чтению обычного текстового файла?
1
 Аватар для KuKu
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
06.02.2015, 18:12
А проблема то конкретно в чем? Не читайте всю строку целиком, а читайте кусками из файла.
1
7 / 7 / 2
Регистрация: 01.03.2013
Сообщений: 142
06.02.2015, 18:21  [ТС]
KuKu, проблема в том что при чтении файла большого размера в котором допустим одна только строка без пробелов приложение упадёт, так как файл читается построчно. А как читать кусками, к примеру читать только по 1000 символов? Объясните пожалуйста
0
 Аватар для KuKu
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
06.02.2015, 18:31
Лучший ответ Сообщение было отмечено timedo1 как решение

Решение

см. read() или read(byte[] b)
1
7 / 7 / 2
Регистрация: 01.03.2013
Сообщений: 142
07.02.2015, 19:10  [ТС]
KuKu, использую read(), но даже при чтении файла 500мб, очень медленно получается. Может я не правильно что то делаю?
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
try(BufferedReader  reader = new BufferedReader(new FileReader("files.txt")))
        {
            
            String line = "";
            
            System.out.println("Start");
            for(int value; (value = reader.read()) != -1; ) {
                char c = (char) value;
                
                line += c;
                
                if( Character.toString(c).equals("\n") ) { 
                    System.out.println(line);
                }
                
            }
            
            reader.close();
            System.out.println("end");
        }catch(Exception e){
           System.out.println("Error : "+e.getMessage());
        }
0
 Аватар для KuKu
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
07.02.2015, 19:42
Цитата Сообщение от timedo1 Посмотреть сообщение
line += c;
Каждую итерацию создаются мегабайтные строки. И лучше за раз считывать не по одному байту.
Сюда можно еще глянуть.
1
7 / 7 / 2
Регистрация: 01.03.2013
Сообщений: 142
08.02.2015, 00:28  [ТС]
KuKu, спасибо большое за советы. Мне как то трудно это дается, не как не пойму работу с памятью. Посмотрите пожалуйста код ниже, я хоть в правильном направлении? Подскажите пожалуйста что я не так делаю

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
try(BufferedReader  reader = new BufferedReader(new InputStreamReader(new FileInputStream("t.txt"))))
        {
            
            char[] barray = new char[1024];
            
            int nRead;
            String line = "";
    
            
            while( (nRead=reader.read(barray, 0, barray.length)) != -1 ) {
                for(int i = 0; i < nRead; i++) {
                    line += barray[i];
                    
                }
                System.out.println(line);
            } 
            
         reader.close();
0
 Аватар для KuKu
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
08.02.2015, 11:10
Цитата Сообщение от timedo1 Посмотреть сообщение
line += barray[i];
Так делать нельзя. Эта запись не добавляет к текущей строке один символ, а создает новую строку. И так каждую итерацию создается строка размером от нескольких килобайт до мегабайт/гигабайт. Используйте StringBuilder или просто найдите индекс необходимого символа, а потом прочтете за раз нужный кусок.
1
7 / 7 / 2
Регистрация: 01.03.2013
Сообщений: 142
08.02.2015, 20:22  [ТС]
KuKu, пробую использовать StringBuilder. Задача: Вывести строку в которой встречается вводимое слово. Вот как я это делаю: Сначала идет перебор по символам, каждый символ добавляется в stringB.append(barray[i]);, если мы встречаем перенос строки .equals("\n"), то очищаем StringBuilder вот так stringB.delete(0, stringB.length()); и ищем дальше, а если в этой строке совпадают символы с нужным словом, то выводим строку.
Проблемы: строка может быть очень длинная и StringBuilder в строке stringB.append(barray[i]); выбрасывает OutOfMemoryError. Нужно как то задать размер к примеру:
Java
1
2
3
    if(stringB.length() > 27748734) {
                        stringB.delete(0, stringB.length());
                    }
Но тогда нужно наверно создать два StringBuilder или...я не знаю, подскажите как быть.


Ниже код:

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
private static String wordToFind = "findWord"; //слово которое нужно найти
    static long startTime, endTime; 
    static boolean finwWordLine = false;
    
    
    public static void main(String[] args) throws FileNotFoundException, IOException {
        
        int endWord = wordToFind.length(); //длина слова
        int startWord = 0;  //счетчик для слова
        String myWord = ""; 
        int numbLine = 1; //подсчет линий
        
        
        char[] barray = new char[1024]; //размер массива
        StringBuilder stringB = new StringBuilder(); //вот тут будут храниться строки
        
        try(BufferedReader  reader = new BufferedReader(new InputStreamReader(new FileInputStream("files.txt"))))
        {   
            startTime = System.currentTimeMillis();
            int value;
            while((value = reader.read(barray, 0, barray.length)) != -1) {
                for(int i = 0; i < value; i++) {
                    
                    stringB.append(barray[i]); //добавляем символы
                    
                    if( Character.toString(barray[i]).equals("\n") ) { //если перенос строки то
                        
                        if(finwWordLine) { //если есть слово в строке
                            System.out.println(numbLine + ": " +stringB.toString()); //то выводим
                        }
                        
                        stringB.delete(0, stringB.length()); //очищаем
                        finwWordLine = false; //выключаем
                        numbLine++; //считаем строки
                    }
                    
                    if(wordToFind.charAt(startWord) == barray[i]){ //если совпадают символы в строке с нужным словом
                        
                        startWord++; //счетчик ++
                        myWord += barray[i]; //создаем слово
                        
                        //output word
                        if(startWord >= endWord){ 
                            if (startWord == endWord) { //если длина совпала с длиной слова  
                                finwWordLine = true; //то выводим строку 
                            } 
                            startWord = 0;
                            myWord = "";
                        } 
                    }
                } 
                
                
                endTime = System.currentTimeMillis();
            }
            
            reader.close();
            
            
           System.out.println("Took: " + (endTime - startTime) + "ms");
 
            
        
        }catch(Exception e){
           System.out.println("Error : "+e);
        }
Добавлено через 31 минуту
UPD: не пойму еще одно. Почему если я хочу найти слово "самолёт" в файле:
one line
two line
three line asd asdas das dasd asd
what of fack полёт
five line
в Европе и США. Первый самолёт был поставлен в конце апреля 1988 г. американской авиакомпании American Airlines.


В конце сентября 1988 г. состоялся первый полёт варианта с двигателями фирмы Pratt & Whitney, поставки начались в
то мне выводит:
6: в Европе и США. Первый самолёт был поставлен в конце апреля 1988 г. американской авиакомпании American Airlines.

9: В конце сентября 1988 г. состоялся первый полёт варианта с двигателями фирмы Pratt & Whitney, поставки начались в
в 9 строке ведь нет слова самолёт, проверка вроде как должно верно работать.
0
17 / 17 / 7
Регистрация: 05.09.2012
Сообщений: 246
08.02.2015, 21:53
Вот альтернативный подход. Для вариантов, где огромные строки без разрывов. Считывает не всю строку, а поочерёдно по одному символу, добавляя их в стринг билдер. Билдер работае по принципу очереди - первый в - первый из. Длинна билдера равна искомому слову. После сравнения содержимого билдера с искомой строкой, из билдера удаляется первая буква, и добавляется в конец следующая из файла. Если совпадение найдено, то номер начальной буквы из строки, где найдено искомое слово, записывается в АррейЛист. Пробовал на файле размером в 100 мегабайт на не очень новом компе. В файле были случано сгенерированные буквы латинского алфавита, без пробелов и без переносов строки (ну то есть одна строка размером в 100 мегабайт). Заняло 16 мин, но думаю можна и побыстрее если б комп был новее.
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
 
public class BigFileRead3 {
 
    static int c;
    static String srch = "umrmp";
    static byte appState = 1;
    static ArrayList<Long> ar = new ArrayList<Long>();
    static long count = 0;
    static StringBuilder sbld = new StringBuilder("");
    static FileInputStream fis;
 
    static void appendV() {
        try {
            if (appState == -1) {
//                System.out.println("sb in append :" + sbld + " appState " + appState);
                c = fis.read();
//                System.out.println("c in put :" + c);
 
                sbld.append((char) c);
                count++;
                appState = 1;
//                System.out.println("sb after " + count + " append : " + sbld + " , appState " + appState);
            }
 
        } catch (IOException exc) {
            System.out.println("Error opening file.");
        }
    }
 
    static void compV() {
        if (appState == 1) {
//            System.out.println("sb in comp : " + sbld + " appState " + appState);
 
            if (sbld.toString().equals(srch)) {
                ar.add(count);
                System.out.println(ar);
            }
            appState = 0;
//            System.out.println("appState after comp change : " + appState);
        }
    }
 
    static void removeV() {
 
        if (appState == 0) {
//            System.out.println("sb in remove :" + sbld + " appState in remove " + appState);
 
            sbld.deleteCharAt(0);
            appState = -1;
//            System.out.println("sb after " + count + " remove : " + sbld + " appState after remove " + appState);
        }
    }
 
    public static void main(String[] args) {
        try {
            fis = new FileInputStream("e:/1.txt");
 
            for (int i = 0; i < srch.length(); i++) {
                sbld.append((char) fis.read());
            }
            System.out.println("Initial sb :" + sbld);
        } catch (IOException e) {
            System.out.println("File not found");
        }
 
        while (c != -1) {
            appendV();
            compV();
            removeV();
 
        }
        System.out.println(ar);
 
    }
 
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.02.2015, 21:53
Помогаю со студенческими работами здесь

Чтение текстового файла
Добрый день , я только недавно начал обучение кодингу но меня вызвали на школьное состязание задание будет таковым у меня есть файл нужно...

Чтение из текстового файла
Дан файл с примерным содержанием: 1 кг 2 кг 1 тонна 3 центнера На экран должно выводиться 1 кг = 1000г ...

Чтение из текстового файла
у меня вопрос вопросов )) import java.io.*; class OpenFile { int array = new int ; public void open_file (String args){ ...

Чтение из текстового файла
Необходимо вместо массива in взять данные из файла .txt лежащего по адресу, к примеру, с:\\123.txt. Не подскажете как это лучше сделать?...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru