crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Загрузка большого текстового файла, Проблемы с загрузкой
ALeXUI
  опции профиля:
сообщение 17.12.2012, 23:13
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 19
Регистрация: 30.4.2011
Пользователь №: 2647

Спасибо сказали: 2 раз(а)




Репутация:   0  


Здравствуйте, столкнулся со следующей проблемой.
Необходимо загрузить и обработать, большой текстовый файл, примерно 20 мб.
И желательно его вывести, например, в qtextedit или что-нибудь подобное.

Самы простой вариант дико загружает компьютер:


        QFile Filetxt;
        Filetxt.setFileName(PathName);
        Filetxt.open(QIODevice::ReadOnly);
        QTextStream textStream;
        textStream.setDevice(&Filetxt);        
        MainTextEdit->append(textStream.readAll());
        Filetxt.close();








Подскажиет пожалуйста, как это сделать лучше?

Нужно распарсить каждую строчку, там находятся данные, по которым строить графики.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Snake174
  опции профиля:
сообщение 18.12.2012, 4:28
Сообщение #2


Студент
*

Группа: Участник
Сообщений: 89
Регистрация: 18.4.2011
Из: Миасс
Пользователь №: 2613

Спасибо сказали: 9 раз(а)




Репутация:   0  


Я создавал буфер для содержимого файла char *data = new char[ file_size ], читал в него содержимое и в QTextEdit выводил только ту часть, которая видна в данный момент. Если в QTextEdit влазит, например 20 строк, то зачем показывать все остальные. Это как при программировании графики, когда нужно отсекать то, что не попадает в камеру, чтобы лишнее не рисовалось. Файлы были размером до 200 Мб и всё летало. Я так понял дико загружает компьютер то, что в QTextEdit постоянно грузятся данные и Qt пытается всё это перерисовывать.

Сообщение отредактировал Snake174 - 18.12.2012, 4:31
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
_Vitaliy_
  опции профиля:
сообщение 18.12.2012, 10:24
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 59
Регистрация: 20.11.2008
Пользователь №: 428

Спасибо сказали: 3 раз(а)




Репутация:   0  


Все зависит от того, какого рода содержимое файла. Если это к примеру данные, структура которых повторяется в каждой строке то считывается строка, затем парсится и записывается в например в модель. Если это Вам подходит то могу скинуть часть кода (если сами не разберетесь).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ALeXUI
  опции профиля:
сообщение 18.12.2012, 12:34
Сообщение #4


Студент
*

Группа: Участник
Сообщений: 19
Регистрация: 30.4.2011
Пользователь №: 2647

Спасибо сказали: 2 раз(а)




Репутация:   0  


Цитата
Если в QTextEdit влазит, например 20 строк, то зачем показывать все остальные. Это как при программировании графики, когда нужно отсекать то, что не попадает в камеру, чтобы лишнее не рисовалось.


Не могли бы привести кучовек кода, не могу понять, как это реализовать?) Но идея мне нравиться)

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


Да так и есть, структура повторяется в каждой строчке. Буду очень благодарен за пример кода)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Snake174
  опции профиля:
сообщение 18.12.2012, 12:59
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 89
Регистрация: 18.4.2011
Из: Миасс
Пользователь №: 2613

Спасибо сказали: 9 раз(а)




Репутация:   0  


Создаёшь скроллбар, ставишь его рядом с QTextEdit-ом:
scrollBar = new QScrollBar( ... );
scrollBar->setOrientation( Qt::Vertical );
connect( scrollBar, SIGNAL(valueChanged(int)), this, SLOT(sbValueChanged(int)) );


Раскрывающийся текст

//------------------------------------------------------------------------------
void MainWindow::sbValueChanged( int value )
{
  TextEdit *viewer = dynamic_cast<TextEdit *>( pTabs->currentWidget() );

  int ind = pTabs->tabToolTip( pTabs->currentIndex() ).toInt();
  int cnt = 0;
  int pos = 0;
  int pos1 = 0;

  int mib = encodingComboBox->itemData( encodingComboBox->currentIndex() ).toInt();
  QTextCodec *codec = QTextCodec::codecForMib( mib );
  QTextStream in( &encodedData[ ind ] );

  in.setAutoDetectUnicode( false );
  in.setCodec( codec );

  QByteArray::ConstIterator itEnd = encodedData[ ind ].constEnd();

  for (QByteArray::ConstIterator it = encodedData[ ind ].constBegin(); it != itEnd; ++it)
  {
    if (*it == '\n')
      ++cnt;

    if (cnt == value)
    {
      pos = std::distance( encodedData[ ind ].constBegin(), it );
      cnt = 0;

      do
      {
        ++it;

        if (it == itEnd)
        {
          pos1 = std::distance( encodedData[ ind ].constBegin(), it );
          break;
        }

        if (*it == '\n')
          ++cnt;
      }
      while (cnt != visibleRowCount);

      pos1 = std::distance( encodedData[ ind ].constBegin(), it );

      break;
    }
  }

  in.seek( pos );
  viewer->clear();
  viewer->appendPlainText( in.read( pos1 - pos ) );
  in.device()->close();
}
//------------------------------------------------------------------------------
void MainWindow::resizeEvent( QResizeEvent *event )
{
  TextEdit *viewer = dynamic_cast<TextEdit *>( pTabs->currentWidget() );
  QFontMetrics fm( viewer->font() );

  visibleRowCount = viewer->height() / fm.height();

  QMainWindow::resizeEvent( event );
}
//------------------------------------------------------------------------------
// После загрузки файла в encodedData вызываешь этот слот
void MainWindow::updateTextEdit()
{
  TextEdit *viewer = dynamic_cast<TextEdit *>( pTabs->currentWidget() );
  viewer->clear();

  int mib = encodingComboBox->itemData( encodingComboBox->currentIndex() ).toInt();
  QTextCodec *codec = QTextCodec::codecForMib( mib );
  int ind = pTabs->tabToolTip( pTabs->currentIndex() ).toInt();
  QTextStream in( &encodedData[ ind ] );

  int data_size = encodedData[ ind ].size();
  int bytesToRead = 0;
  rowCount = 0;

  QByteArray::ConstIterator itEnd = encodedData[ ind ].constEnd();

  for (QByteArray::ConstIterator it = encodedData[ ind ].constBegin(); it != itEnd; ++it)
  {
    if (*it == '\n')
      ++rowCount;

    if (rowCount == visibleRowCount || it == itEnd)
      bytesToRead = std::distance( encodedData[ ind ].constBegin(), it );
  }

  viewer->appendPlainText( in.read( bytesToRead ) );

  scrollBar->setMaximum( rowCount );

  viewer->moveCursor( QTextCursor::Start );
}



encodedData - массив QByteArray

У QTextEdit-a делаешь:
setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );

Ну что-то типа этого у меня было.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
_Vitaliy_
  опции профиля:
сообщение 18.12.2012, 19:54
Сообщение #6


Студент
*

Группа: Участник
Сообщений: 59
Регистрация: 20.11.2008
Пользователь №: 428

Спасибо сказали: 3 раз(а)




Репутация:   0  


У меня данные в строке разделялись как минимум одним пробелом. Если у Вас это так, то действовать можно по следующему алгоритму.
1. в *.h пишем: QStandardItemModel *model;
2. в *.cpp в конструкторе: model = new QStandardItemModel(this);
3. здесь привожу часть своего рабочего кода (некоторые "вещи" опущены) главное уловить смысл
Раскрывающийся текст
int currentRow = 0;
QCoreApplication::processEvents(); // chtobi prilozhenie ne zavisal

QStandardItem *item = 0;
while (!stream.atEnd())
{
fields = stream.readLine().simplified().split(' '); // razdelitel !!!
for (int i = 0; i < columnCount; ++i)
{
item = new QStandardItem(fields.at(i));
model->setItem(currentRow, i, item);
}
++currentRow;
}

4. далее по коду, например у меня это было отдельное окно
Раскрывающийся текст
QDialog *dialog = new QDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setWindowTitle("Data ...");
...

QTableView *view = new QTableView(dialog); /// QTableView (&dialog)
view->setModel(model);
...

dialog->show();

удобно тем, что данные хранятся в модели, а с моделью довольно просто работать.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ALeXUI
  опции профиля:
сообщение 13.2.2013, 11:00
Сообщение #7


Студент
*

Группа: Участник
Сообщений: 19
Регистрация: 30.4.2011
Пользователь №: 2647

Спасибо сказали: 2 раз(а)




Репутация:   0  


Vitaliy, огромное Вам спасибо, вернулся к этой задаче, и все получилось очень здорово!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_*
сообщение 13.9.2013, 9:20
Сообщение #8





Гости








    


Цитата(Snake174 @ 18.12.2012, 4:28) *
Я создавал буфер для содержимого файла char *data = new char[ file_size ], читал в него содержимое и в QTextEdit выводил только ту часть, которая видна в данный момент. Если в QTextEdit влазит, например 20 строк, то зачем показывать все остальные. Это как при программировании графики, когда нужно отсекать то, что не попадает в камеру, чтобы лишнее не рисовалось. Файлы были размером до 200 Мб и всё летало. Я так понял дико загружает компьютер то, что в QTextEdit постоянно грузятся данные и Qt пытается всё это перерисовывать.


Не так уж и летает! Реализовал Ваш алгоритм. Если просматривать файл в 200 Mb, то конец файла очень медлительный. Это и не удивительно - так как постоянно приходится проходить весь файл при вычислении значения pos
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Snake174
  опции профиля:
сообщение 16.9.2013, 5:58
Сообщение #9


Студент
*

Группа: Участник
Сообщений: 89
Регистрация: 18.4.2011
Из: Миасс
Пользователь №: 2613

Спасибо сказали: 9 раз(а)




Репутация:   0  


Цитата(Гость @ 13.9.2013, 9:20) *
Цитата(Snake174 @ 18.12.2012, 4:28) *
Я создавал буфер для содержимого файла char *data = new char[ file_size ], читал в него содержимое и в QTextEdit выводил только ту часть, которая видна в данный момент. Если в QTextEdit влазит, например 20 строк, то зачем показывать все остальные. Это как при программировании графики, когда нужно отсекать то, что не попадает в камеру, чтобы лишнее не рисовалось. Файлы были размером до 200 Мб и всё летало. Я так понял дико загружает компьютер то, что в QTextEdit постоянно грузятся данные и Qt пытается всё это перерисовывать.


Не так уж и летает! Реализовал Ваш алгоритм. Если просматривать файл в 200 Mb, то конец файла очень медлительный. Это и не удивительно - так как постоянно приходится проходить весь файл при вычислении значения pos

Ты бы ещё лет через 5 ответ написал. К тому же _Vitaliy_ предложил отличный вариант, сделал также, всем доволен.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 23.11.2024, 2:53