Russian Qt Forum
Ноябрь 26, 2024, 00:53 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Помочь с функцией  (Прочитано 6086 раз)
koldun90
Крякер
****
Offline Offline

Сообщений: 345


Просмотр профиля
« : Сентябрь 29, 2014, 10:32 »

Здравствуйте есть функция которая добавляет в начало каждого файла слово "zashifrovano" она корректно работает только с файлами небольшого объема)
но тут небольшая загвоздка если файл допустим размером достаточно большой допустим 50 или 100 мегабайт программа вываливается в ошибку сигментирования
Как можно сделать так чтобы файлы больших объемов(файлы 500 мегов ,1 гиг или 2) функция обрабатывала корректно)?
Код:
void priznakshifr(QString put)  //put-- полный путь исходного файла
{
    QMessageBox msg;
    msg.setText(QString::fromLocal8Bit("исходный файл")+put);
    msg.exec();

    //put исходный файл

     //переводим старое имя файла в указатель на char
    char *imystarfaila= put.toLocal8Bit().data();


    QFile file(put);  //определяем размер старого файла в байтах //файл после кодировки-outfilepath
    qint64 pere=file.size();  // УЗНАЕМ РАЗМЕР ФАЙЛА В БАЙТАХ
    msg.setText(QString::number(pere));
    msg.exec();
    char buf[pere];  // создаем буффер для хранения информации старого файла

    QString rr=put;
    QString novfail=rr+"1";   //имя нового временного файла  //ИМЯ ВРЕМЕННОГО ФАЙЛА
    //QString novfail=put+"1";
    QByteArray br=novfail.toLocal8Bit();   // переводим новое имя файла в указатель на char
    char *imynovfaila=br.data();

    ofstream f(imynovfaila);   //открываем новый временный файл (если его нет то создаем его автоматически)
    f<<"zashifrovano";  // пишем в него ключевую фразу

    ifstream g;
    g.open(imystarfaila);   // открываем старый файл
    g.read(buf,pere);  // читаем данные в буфер из старого файла
    f.write(buf,pere);  // пишем из буфера в новый файл

    file.remove();  //удаляем старый файл

    QFile file2(novfail);   // переименовываем новый файл в имя старого
    file2.rename(put);


    g.close();
    f.close();


}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Сентябрь 29, 2014, 10:47 »

Напр так

Код
C++ (Qt)
// файлы должны быть открыты и позиции записи/чтения установлены
bool CopyFrom( QFile & inF, QFile & outF, qint64 total = -1 )
{
 char buf[64 * 1024];
 if (total < 0)
  total = inF.size() - inF.pos();
 while (total > 0) {
   qint64 num = qMin(total, (qint64) sizeof(buf));
   inF.read(buf, num);
   outF.write(buf, num);
   if (inF.error() || outF.error()) return false;
   total -= num;
 }
 return true;
}
« Последнее редактирование: Сентябрь 29, 2014, 11:06 от Igors » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #2 : Сентябрь 29, 2014, 11:05 »

Код
C++ (Qt)
// файлы должны быть открыты и позиции записи/чтения установлены
bool CopyFrom( QFile & inF, QFile & outF, qint64 total = -1 )
{
 char buf[64 * 1024];
 if (total < 0)
  total = inF.size() - inF.pos();
 while (total > 0) {
   qint64 num = qMax(total, (qint64) sizeof(buf));   // <<<<<    ???
   inF.read(buf, num);
   outF.write(buf, num);
   if (inF.error() || outF.error()) return false;
   total -= num;
 }
 return true;
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Сентябрь 29, 2014, 11:06 »

Точно, описАлся, подправил  Улыбающийся
Записан
vulko
Гость
« Ответ #4 : Сентябрь 29, 2014, 15:08 »

Если нужно именно переименовать, то есть отличная статичная функция и не нужно городить велосипед.

Код:
QFile::rename("C:/oldlocation/oldname.txt", "C:/newlocation/newname.txt");
Записан
koldun90
Крякер
****
Offline Offline

Сообщений: 345


Просмотр профиля
« Ответ #5 : Сентябрь 29, 2014, 15:13 »

  Пишу код  
Код:
   QFile file1(put);

    QString novfail=put+"1";   //имя нового временного файла  //ИМЯ ВРЕМЕННОГО ФАЙЛА

    QByteArray br=novfail.toLocal8Bit();   // переводим новое имя файла в указатель на char
    char *imynovfaila=br.data();

    ofstream f(imynovfaila); //пишем в новый файл 12 байт
    f<<"zashifrovano";
    f.close();

    QFile file2(novfail);  //новый файл

  
   file1.open(QIODevice::ReadOnly);  // открываем исходный файл для чтения
    file2.open(QIODevice::Append); //открываем новый файл для дозаписи в конец
    bool ok=CopyFrom(file1,file2,0);

ругается в строке
Код:
bool ok=CopyFrom(file1,file2,0);
пишет что тип QFile::file1 QFile::file2 приватный
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Сентябрь 29, 2014, 15:42 »

Выкиньте нафиг тот ofstream, и не лепите русские слова латиницей (novfail)
Код
C++ (Qt)
QFile outF(put + "1");
outF.open(QIODevice::WriteOnly | QIODevice::Truncate);
 
const char * sign = "zashifrovano";   // "encrypted"
outF.write(sign, strlen(sign));
 
QFile inF(put);
inF.open(QIODevice::ReadOnly);
bool ok = CopyFrom(inF, outF);
И имя переменной "put" очень плохо, замените. В общем как в том анекдоте
Цитировать
хорошо, только "эх" уберите - цыганщиной отдает
Улыбающийся
Записан
OKTA
Гость
« Ответ #7 : Сентябрь 29, 2014, 16:02 »

Igors, а QIODevice::Truncate сам по себе не выставляется разве? Зачем его принудительно указывать?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Сентябрь 29, 2014, 16:19 »

Igors, а QIODevice::Truncate сам по себе не выставляется разве? Зачем его принудительно указывать?
Очень мало работал на линуксе - но вот там за его отсутствие получил по дюнделю  Улыбающийся
Записан
OKTA
Гость
« Ответ #9 : Сентябрь 29, 2014, 16:24 »

ох уж эти двойные стандарты!  Смеющийся
Записан
koldun90
Крякер
****
Offline Offline

Сообщений: 345


Просмотр профиля
« Ответ #10 : Сентябрь 30, 2014, 20:31 »

вообщем не работает ваш алгоритм с файлами 500 мегов и более
Записан
Alexu007
Гость
« Ответ #11 : Сентябрь 30, 2014, 22:56 »

Вот так?

Код
C++ (Qt)
   QByteArray fl_header(320, 0);
 
   ......
 
   // открываем файлы
   QFile inpf(full_fname);
   QFile outf(out_fname);
 
   // для чтения
   if (!inpf.open(QIODevice::ReadOnly))
       {
       msgBox.setText("Error: can't open input file");
       msgBox.exec();
       goto met_ret;
       }
 
   // для записи
   if (!outf.open(QIODevice::WriteOnly))
       {
       msgBox.setText("Error: can't open output file");
       msgBox.exec();
       goto met_ret;
       }
 
 
   // записываем заголовок
   outf.write(fl_header);
 
 
   cx = 0;
 
   // цикл записи файла
   while(!inpf.atEnd())
       {
       QByteArray src = inpf.read(1024);
       const int sz = src.size();
       QByteArray dst(sz, 0);
 
       for(int i = 0; i < sz; ++i)
           {dst[i] = fn_Shifr_byte(src[i]);}
 
       outf.write(dst);
 
       cx++;
       if(!(cx % 100))
           {
           ui->lineEdit_byt->setText(QString::number(cx));
           QApplication::processEvents();
           }
       }
 
met_ret:
 
   inpf.close();
   outf.close();
« Последнее редактирование: Сентябрь 30, 2014, 23:02 от Alexu007 » Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #12 : Октябрь 05, 2014, 11:56 »

проблема в том что вы читаете весь файл в память , да к тому же ваш экземпляр буфера (строка) находится в стеке, соответственно при попытке считать 50 метров в стек у вас переполнение буфера. Читать файлы целиком в память неправильно (разве что если вы уверены что их размер действительно всегда будет очень маленьким). По хорошему вам нужно читать файл частями + использовать функции QFile::write и QFile::read напрямую, а не использовать строковую переменную в качестве буффера.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.184 секунд. Запросов: 23.