2013-04-18 3 views
3
QTemporaryFile tf; 
tf.open(); 
QDataStream tfbs (&tf); 
tfbs << "hello\r\n" << "world!\r\n"; 
const int pos = int (tf.pos()); 

QByteArray ba; 
ba.append ("hello\r\n"); 
ba.append ("world!\r\n"); 
const int size = ba.size(); 

В основном, мой вопрос: что я делаю неправильно? Почему pos> размер? Должен ли я использовать < <? Должен ли я использовать QDataStream?Разница между QDataStream и QByteArray

Редактировать: Есть ли способ настроить QDataStream или QTemporaryFile так, чтобы оператор < < не добавлял строки с длиной 32 бит и сохранял нулевые терминаторы в файле? Вызов QDataStream :: writeBytes, когда у меня есть только серия цитируемых строк, а QStrings - очень уродливый код.

+0

Возможно, было бы полезно указать, какие 'pos' и' size' на самом деле. – jkerian

+0

pos == 25, size == 15 – cppguy

+0

первый - это поток, второй - массив, они служат совершенно другим целям и часто используются вместе. – dtech

ответ

2

Ответ в документах. Я не собираюсь проходить QByteArray, так как считаю, что это очевидно, что он работает так, как ожидалось.

Оператор QDataStream < < (char *) перегрузка оценивается в the writeBytes() function.

Эта функция выводит:

Записывает длину спецификатора Len и буфер с к потоку и возвращает ссылку на поток. Len сериализуется как quint32, , за которым следуют len байты с s. Обратите внимание, что данные не закодированы.

Так "hello\r\n", я бы ожидать, что выход будет:

0,0,0,8,'h','e','l','l','o','\r','\n',0 

Длина 4 байта, а затем байт из строки. Окончательный NULL с окончанием строки, вероятно, также добавляется в конец, что будет учитывать другие таинственные дополнительные два байта.

+0

Да, я пропустил это. Желание было стандартным более чистым способом записи строк в временный файл – cppguy

+0

@cppguy - возможно, с QTextStream? – dtech

+0

К сожалению, я пишу строки, а затем большой QByteArray. Я надеялся на то, что обрабатывал все эти случаи – cppguy

0

Так что я в конечном итоге писать свой собственный вспомогательный класс для сериализации мои данные:

class QBinaryStream 
{ 
public: 
    QBinaryStream (QIODevice& iod) : m_iod (iod) {} 
    QBinaryStream& operator << (const char* data) 
    { 
     m_iod.write (data); 
     return *this; 
    } 
    QBinaryStream& operator << (const QString& data) 
    { 
     return operator << (data.toUtf8()); 
    } 
    QBinaryStream& operator << (const QByteArray& data) 
    { 
     m_iod.write (data); 
     return *this; 
    } 

private: 
    QIODevice& m_iod; 
}; 
0

Должен ли я не использовать QDataStream?

В вашем случае возможно QTextStream или даже QString будет делать.

Класс QTextStream обеспечивает удобный интерфейс для чтения и текст ввода.

QTextStream может работать с QIODevice, QByteArray или QString. Используя потоковые операторы QTextStream, вы можете удобно читать и писать слова, строки и цифры.

Что касается QByteArray, Qstring предпочтение следует отдавать ему всякий раз, когда это возможно

QByteArray класс обеспечивает массив байтов.

QByteArray может использоваться для хранения как необработанных байтов (в том числе '\ 0's), так и традиционных 8-битных строк с «\ 0» -конечным. Использование QByteArray намного больше более удобно, чем использование const char *.За кулисами всегда гарантирует, что за данными следует терминатор '\ 0', и использует неявный обмен (copy-on-write) , чтобы уменьшить использование памяти и избежать ненужного копирования данных.

В дополнение к QByteArray Qt также предоставляет класс QString для хранения строковых данных . Для большинства целей QString - это класс, который вы хотите использовать. В нем хранятся 16-разрядные символы Юникода, что упрощает хранение символов, отличных от ASCII/не латинского, в приложении. Кроме того, QString используется в API Qt. Два основных случая, когда QByteArray являются подходящими, - это когда вам нужно хранить необработанные двоичные данные, и когда важна сохранность памяти (например, с Qt для встроенного Linux).