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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Частично переписать содержимое бинарного файла  (Прочитано 5107 раз)
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);
« Последнее редактирование: Май 24, 2018, 14:42 от pafo » Записан
qate
Супер
******
Offline Offline

Сообщений: 1175


Просмотр профиля
« Ответ #1 : Май 24, 2018, 12:35 »

Очевидно - надо считать ВЕСЬ файл в qbytearray, замени нужные байты и запиши новый файл
Для мелких файлов это будет нормально так делать
Записан
CTime
Гость
« Ответ #2 : Май 24, 2018, 14:33 »

Размер файлов в среднем около 400мб, не знаю, можно ли такие файлы считать мелкими...
Цитировать
замени нужные байты
вот в этом основной вопрос состоит
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #3 : Май 24, 2018, 14:42 »

Открываешь один файл на чтение, другой на запись. Читаешь из одного, пишешь в другой. Чего не ясно-то?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
qate
Супер
******
Offline Offline

Сообщений: 1175


Просмотр профиля
« Ответ #4 : Май 24, 2018, 16:52 »

400мб для разовой работы не много

если много, делай QFile::copy
затем второй файл открывай на чтение и запись
считывай байты №2 и №3
вычисляй что нужно
пиши их обратно
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Май 25, 2018, 06:19 »

Код
C++ (Qt)
quint16  temp;
// читаем temp
const quint16 mask = 0x7FFF;
quint16 newVal = (temp & ~mask) | ((temp & mask) + 10);
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #6 : Май 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);
 
« Последнее редактирование: Май 25, 2018, 06:34 от Old » Записан
CTime
Гость
« Ответ #7 : Май 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();
    }
}
В правильном ли направлении я двигаюсь? И как все-таки встать на нужную позицию для записи?
Записан
qate
Супер
******
Offline Offline

Сообщений: 1175


Просмотр профиля
« Ответ #8 : Май 25, 2018, 17:24 »

QDataStream тут не нужен, достаточно QFile
А уж если ты считал весь файл в QByteArray, то и seek не нужен

Ты прочитал все рекомендации и все применил их все, получилась каша.
« Последнее редактирование: Май 25, 2018, 17:33 от qate » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Май 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;
}
« Последнее редактирование: Май 26, 2018, 08:50 от Igors » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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