Название: Частично переписать содержимое бинарного файла
Отправлено: CTime от Май 24, 2018, 11:00
Доброго времени суток! Столкнулся с такой задачей. Имеется бинарный файл, заголовок (первые 12 байт) которого имеет вид, приведенный на рисунке (во вложении). Необходимо на основе этого файла создать другой бинарный файл, в котором вместо значения inf3 поместить, например, (значение inf3) + 10. Вопрос в том, как именно дочитать файл до значения inf3, попутно копируя содержимое во второй файл, потом собственно считать значение inf3, прибавить к этому значению 10, записать его, а потом продолжить копирование файла уже до конца? Если не видно, то inf3 занимает не целое количество байт, а 15 бит. В Qt недавно, наверное еще не все инструменты знакомы, поэтому прошу помощи. Заранее огромное спасибо! Собственно достать само значение inf3 у меня вроде получилось: QString inFileName; QString inFilter; inFilter = "Bin files (*.rpu);; All Files (*.*)"; inFileName = QFileDialog::getOpenFileName(0, trUtf8("Select file"), QApplication::applicationDirPath(), inFilter, 0); QFile inFile; inFile.setFileName(inFileName); QString outFileName = inFileName + "_output.rpu"; QFile outFile; outFile.setFileName(outFileName); if (!inFile.open(QIODevice::ReadOnly)) qDebug() << "inFile error"; if (!outFile.open(QIODevice::WriteOnly)) qDebug() << "outFile Error"; QByteArray inArray; inArray = inFile.read(12); QDataStream stream (&inArray, QIODevice::ReadWrite); stream.setByteOrder(QDataStream::LittleEndian); stream.device()->seek(0); quint32 tmp; quint16 inf3; stream.operator >>(tmp) >> (tmp) >> (tmp); inf3 = (tmp&0x00007FFF); qDebug() << inf3; stream.device()->seek(0);
Название: Re: Частично переписать содержимое бинарного файла
Отправлено: qate от Май 24, 2018, 12:35
Очевидно - надо считать ВЕСЬ файл в qbytearray, замени нужные байты и запиши новый файл Для мелких файлов это будет нормально так делать
Название: Re: Частично переписать содержимое бинарного файла
Отправлено: CTime от Май 24, 2018, 14:33
Размер файлов в среднем около 400мб, не знаю, можно ли такие файлы считать мелкими... замени нужные байты вот в этом основной вопрос состоит
Название: Re: Частично переписать содержимое бинарного файла
Отправлено: Пантер от Май 24, 2018, 14:42
Открываешь один файл на чтение, другой на запись. Читаешь из одного, пишешь в другой. Чего не ясно-то?
Название: Re: Частично переписать содержимое бинарного файла
Отправлено: qate от Май 24, 2018, 16:52
400мб для разовой работы не много
если много, делай QFile::copy затем второй файл открывай на чтение и запись считывай байты №2 и №3 вычисляй что нужно пиши их обратно
Название: Re: Частично переписать содержимое бинарного файла
Отправлено: Igors от Май 25, 2018, 06:19
C++ (Qt) quint16 temp; // читаем temp const quint16 mask = 0x7FFF; quint16 newVal = (temp & ~mask) | ((temp & mask) + 10);
Название: Re: Частично переписать содержимое бинарного файла
Отправлено: Old от Май 25, 2018, 06:32
C++ (Qt) quint16 temp; // читаем temp const quint16 mask = 0x7FFF; quint16 newVal = (temp & ~mask) | ((temp & mask) + 10);
Не будет работать как надо. После прибавления результат может изменить старший бит. C++ (Qt) quint16 newVal = (temp & ~mask) | ((temp + 10) & mask);
Название: Re: Частично переписать содержимое бинарного файла
Отправлено: CTime от Май 25, 2018, 14:16
Спасибо всем, кто откликнулся! После всего прочитанного у меня получилось что-то вроде этого: QFile inFile; inFile.setFileName(inFileName); QString outFileName = inFileName + "_output.rpu"; QFile outFile; outFile.setFileName(outFileName); if (!inFile.open(QIODevice::ReadOnly) || (!outFile.open(QIODevice::ReadWrite))) { qDebug() << "some file error"; } else { QByteArray array; array = inFile.readAll(); inFile.close(); QDataStream stream (&array, QIODevice::ReadWrite); stream.setByteOrder(QDataStream::LittleEndian); QDataStream outStream (&outFile); stream.device()->seek(0); quint32 tmp; quint16 inf3; stream.operator >>(tmp) >> (tmp) >> (tmp); inf3 = (tmp&0x00007FFF); qDebug() << inf3; const quint16 mask = 0x7FFF; quint16 newVal = (inf3 & ~mask) | ((inf3 + 10) & mask); qDebug() << newVal; stream.device()->seek(0); //ВСТАТЬ НА НУЖНУЮ ПОЗИЦИЮ stream << newVal; stream.device()->seek(0); outStream << stream; outFile.close(); } } В правильном ли направлении я двигаюсь? И как все-таки встать на нужную позицию для записи?
Название: Re: Частично переписать содержимое бинарного файла
Отправлено: qate от Май 25, 2018, 17:24
QDataStream тут не нужен, достаточно QFile А уж если ты считал весь файл в QByteArray, то и seek не нужен
Ты прочитал все рекомендации и все применил их все, получилась каша.
Название: Re: Частично переписать содержимое бинарного файла
Отправлено: Igors от Май 26, 2018, 08:48
C++ (Qt) // позиция заменяемого числа в файле const qlonglong editOffset = 0; bool Copy2Out( const QString & inFileName ) { // копируем файл 1:1 QString outFileName = inFileName + "_output.rpu"; if (!QFile::copy(inFileName, outFileName)) return Error("File copy error"); // открываем выходной файл QFile file(outFileName); if (!file.open(QIODevice::ReadWrite)) return Error("File write error"); // читаем число для замены quint16 src, dst; file.seek(editOffset); file.read((char *) &src, 2); // меняем const quint16 mask = 0x7FFF; dst = src & mask; dst += 10; if (dst & ~mask) return Error("Overflow Error"); dst |= (src & ~mask); // пишем взад file.seek(editOffset); file.write((char *) &dst, 2); if (file.error() != QFile::NoError) return Error("File Write Error"); return true; }
|