Название: Помочь с функцией
Отправлено: koldun90 от Сентябрь 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();
}
Название: Re: Помочь с функцией
Отправлено: Igors от Сентябрь 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; }
Название: Re: Помочь с функцией
Отправлено: Old от Сентябрь 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; }
Название: Re: Помочь с функцией
Отправлено: Igors от Сентябрь 29, 2014, 11:06
Точно, описАлся, подправил :)
Название: Re: Помочь с функцией
Отправлено: vulko от Сентябрь 29, 2014, 15:08
Если нужно именно переименовать, то есть отличная статичная функция и не нужно городить велосипед. QFile::rename("C:/oldlocation/oldname.txt", "C:/newlocation/newname.txt");
Название: Re: Помочь с функцией
Отправлено: koldun90 от Сентябрь 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 приватный
Название: Re: Помочь с функцией
Отправлено: Igors от Сентябрь 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" очень плохо, замените. В общем как в том анекдоте хорошо, только "эх" уберите - цыганщиной отдает :)
Название: Re: Помочь с функцией
Отправлено: OKTA от Сентябрь 29, 2014, 16:02
Igors, а QIODevice::Truncate сам по себе не выставляется разве? Зачем его принудительно указывать?
Название: Re: Помочь с функцией
Отправлено: Igors от Сентябрь 29, 2014, 16:19
Igors, а QIODevice::Truncate сам по себе не выставляется разве? Зачем его принудительно указывать?
Очень мало работал на линуксе - но вот там за его отсутствие получил по дюнделю :)
Название: Re: Помочь с функцией
Отправлено: OKTA от Сентябрь 29, 2014, 16:24
ох уж эти двойные стандарты! ;D
Название: Re: Помочь с функцией
Отправлено: koldun90 от Сентябрь 30, 2014, 20:31
вообщем не работает ваш алгоритм с файлами 500 мегов и более
Название: Re: Помочь с функцией
Отправлено: Alexu007 от Сентябрь 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();
Название: Re: Помочь с функцией
Отправлено: Fregloin от Октябрь 05, 2014, 11:56
проблема в том что вы читаете весь файл в память , да к тому же ваш экземпляр буфера (строка) находится в стеке, соответственно при попытке считать 50 метров в стек у вас переполнение буфера. Читать файлы целиком в память неправильно (разве что если вы уверены что их размер действительно всегда будет очень маленьким). По хорошему вам нужно читать файл частями + использовать функции QFile::write и QFile::read напрямую, а не использовать строковую переменную в качестве буффера.
|