ДТ
Даниил ТетеринNov. 8, 2018, 6:10 a.m.

Чтение из большого файла

file

Проблема такая: одним из домашних заданий по программированию(первый курс) было написание блокнота. Т.е. ридера текстовых файлов. Это я, собственно, сделал, но есть небольшой нюанс - при открытии ОЧЕНЬ больших файлов (например, если в диалоговом окне выбора файла написать *.* , то можно будет, в обход запрету на разрешение файлов, открыть какой-нибудь блю-рей фильм на 30+ гб), программа погибает в агонии и с криками ( код ошибки : 3). Причем, если открывать нормальным блокнотом, что идет вместе с виндой, то он спокойно "переваривает" любой блю-рей. Каким образом это можно решить?

QFile file(QFileDialog::getOpenFileName(this,"Открыть файл","C:\\", tr("Текстовые файлы (*.txt);;Файлы C++ (*.cpp *.h)")));
        if (!file.open(QFile::ReadOnly | QFile::Text))
            return;
        QTextStream stream(&file);
        stream.setCodec("UTF-8");
        QString tempStr;
        while(!stream.atEnd())
            tempStr.append(stream.read(10000));
        ui->_mainTextField->setText(tempStr);
        MainWindow::setWindowTitle(file.fileName());
        fileName = file.fileName();
        tempStr = nullptr;
        file.flush();
        file.close();

Screenshot_2.png
We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

6
Evgenii Legotckoi
  • Nov. 8, 2018, 8:09 a.m.

Сдаётся мне, что у вас на ПК просто память кончается, а в обычном блокноте там каким-то способом реализована частичная подгрузка.

Просто QString tmpStr сам по себе не в состоянии съесть 30 гигабайт за раз, скорее всего падает в цикле while, надо проверять это момент, но наверняка там.

Тут вопрос в том, что вы хотите? Я бы сделал дополнительную проверку на тип файла и возможно размер и запретил бы открывать такой файл.


    IF
    • Nov. 8, 2018, 10:31 a.m.

    Доброго времени суток.

    Вы используете очень скользкий путь чтения файла(цикл пока не конец).

    в цикле открывать файл на чтение и забирать по 10000 позиций - вот главная ошибка. А с кодом 3 он вылетает скорее всего потому что у вас оперативная память кончается - и идёт запрос на жёсткий диск, далее несколько больших запросов и ядро просит удалить данный процесс.


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


      linq
      • Nov. 8, 2018, 1:47 p.m.

      Учитывая вышесказанное могу добавить,что необходимо читать из файла как минимум блоками,размером с буфер страницы,и выводить в текстовое поле виджета или как там у тебя реализовано по-блочно,ну и вообще надо полагать как минимум из аппаратных возможностей,если у тебя 4 гига ОЗУ,а ты пытаешься в него загрузить 30 GB,то эо не есть нормально.

        ДТ
        • Nov. 11, 2018, 3:09 p.m.

        Чуть переписал код, программа, ожидаемо, перестала падать при открытии больших файлов. Но все равно зависает при попытке открыть хоть сколько-нибудь большой файл. А дожидаться открытия я уж не стал. Стыдно, на самом деле, что я сам не подумал о том, что скидывать всё в одну строку - глупо.

        Хотя стандартный блокнот, опять же, довольно резво открыл экзешник на 900 мб, когда моя поделка попросту захлебнулась. Мне все еще интересно, каким образом это сделано там.


        QString tempStr;
                ui->_mainTextField->clear();
                while(!stream.atEnd())
                {
                    tempStr.append(stream.read(10000));
                    if(tempStr.size() >= 100000)
                    {
                        ui->_mainTextField->append(tempStr);
                        tempStr.clear();
                    }
                }
                ui->_mainTextField->append(tempStr);
                changesIs = false; 

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

          Как сайты подгружают контент по мере прокрутки страницы

            IF
            • Nov. 12, 2018, 4:37 a.m.

            Доброго времени суток.


            Евгений прав.


            Вам надо перестроить приложение нарпимер по такой логике.


            У вас есть поле - куда вы выводите содержимое текстового файла, рассчитываете сколько символов помещается на "данный момент" в окно.

            Далее открываете файл на чтение и считываете сколько всего занимает данный файл - и выполняете "разметку скролбара".


            Под "разметкой скролбара" приведу пример:

            Например у вас есть файл, в нём 1000 символов, а в окно помещается 100, получается , что полоска скролбара дожна занимать на данный момент 100/1000 - 1/10 часть всего скролбара.


            Далее вы выполняете отрисовку тех самый(из примера) 100 символов на сцену.


            Евгений подчеркнул, что нужно увязать сигнал передвижения скролбара и слот перерисовки сцены.

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

            Воздможно улучшение например в качестве хэширования данных при запросе из файла - это ускорит приложение, но займёт чуть больше памяти при хранении данных - ЗА СЁ НУЖНО ПЛАТИТЬ.


            Хорошего дня и удачи в кодинге.



              Comments

              Only authorized users can post comments.
              Please, Log in or Sign up
              AD

              C ++ - Test 004. Pointers, Arrays and Loops

              • Result:50points,
              • Rating points-4
              m

              C ++ - Test 004. Pointers, Arrays and Loops

              • Result:80points,
              • Rating points4
              m

              C ++ - Test 004. Pointers, Arrays and Loops

              • Result:20points,
              • Rating points-10
              Last comments
              i
              innorwallNov. 15, 2024, 10:27 a.m.
              Release of C++/Qt and QML application deployment utility CQtDeployer v1.4.0 (Binary Box) optionally substituted alkoxy, optionally substituted alkenyloxy, optionally substituted alkynyloxy, optionally substituted aryloxy, OCH, OC H, OC H, OC H, OC H, OC H, OC H, O C CH, OCH CH OH, O…
              i
              innorwallNov. 15, 2024, 5:26 a.m.
              Qt/C++ - Lesson 031. QCustomPlot – The build of charts with time buy generic priligy We can just chat, and we will not lose too much time anyway
              i
              innorwallNov. 15, 2024, 3:03 a.m.
              Qt/C++ - Lesson 060. Configuring the appearance of the application in runtime I didnt have an issue work colors priligy dapoxetine 60mg revia cost uk August 3, 2022 Reply
              i
              innorwallNov. 14, 2024, 8:07 p.m.
              Circuit switching and packet data transmission networks Angioedema 1 priligy dapoxetine
              i
              innorwallNov. 14, 2024, 7:42 p.m.
              How to Copy Files in Linux If only females relatives with DZ offspring were considered these percentages were 23 order priligy online uk
              Now discuss on the forum
              i
              innorwallNov. 14, 2024, 11:39 a.m.
              добавить qlineseries в функции priligy amazon canada 93 GREB1 protein GREB1 AB011147 6
              i
              innorwallNov. 11, 2024, 6:55 p.m.
              Всё ещё разбираюсь с кешем. priligy walgreens levitra dulcolax carbs The third ring was found to be made up of ultra relativistic electrons, which are also present in both the outer and inner rings
              9
              9AnonimOct. 25, 2024, 4:10 p.m.
              Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

              Follow us in social networks