我的问题是变量内容始终为空。 这是我的代码:
QFile file("/home/qt/Client/file.txt");
if(file.open(QIODevice::ReadOnly)){
qDebug("File opened");
}
QDataStream fileData(&file);
QByteArray content;
QDataStream out(&content, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_7);
out << static_cast<quint16>(0) << "file" << "/home/qt/Client/file.txt" << fileData;
out.device()->seek(0);
out << static_cast<quint16>(content.size());
qDebug() << content.constData();
tcpSocket->write(content);
输出:
File opened
内容始终为空
感谢您的帮助
答案 0 :(得分:4)
content
不为空,但如果您将其解释为C样式的0终止字符串,则显示为为空。
当你写:
out.device()->seek(0);
out << static_cast<quint16>(content.size());
这将以大端格式将content
的前两个字节设置为content.size()
(这是默认值)。因此,如果content.size()
小于255,则content.constData()
的第一个字节将为0('\0'
)。任何尝试使用期望C样式字符串的函数打印constData()
都不会输出任何内容,因为您的“字符串”以“字符串结束”标记开头。
如果您想查看content
的完整内容,则应分别打印所有字符,并使用hexdump
之类的内容查看原始数据。
如果我这样做而不是qDebug() << content.constData();
:
for (int i=0; i<content.size(); i++) {
std::cout << content.constData()[i];
}
运行时输出(文件只包含20个'a'
个字符):
$ ./qt | hexdump -C
00000000 00 40 00 00 00 05 66 69 6c 65 00 00 00 00 19 2f |.@....file...../|
00000010 68 6f 6d 65 2f 71 74 2f 43 6c 69 65 6e 74 2f 66 |home/qt/Client/f|
00000020 69 6c 65 2e 74 78 74 00 00 00 00 14 61 61 61 61 |ile.txt.....aaaa|
00000030 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |aaaaaaaaaaaaaaaa|
00000040
如果我曾经使用过:
std::cout << content.constData();
因为第一个0字符,所以没有输出。
如果你的数据更长,并且content
的大小大于255,那么第一个字符将不再是0,但是你将打印两个字符的垃圾而没有任何内容否则因为Qt通过首先写入它的长度(这里是32位),然后是其内容来序列化QString(和大多数其他类型)。由于它采用大端符号表示,因此第一个字节很可能为0。
带注释的输出:
00000000 00 40 00 00 00 05 66 69 6c 65 00 00 00 00 19 2f |.@....file...../|
<u16> < str len > < str data > < str len > <
00000010 68 6f 6d 65 2f 71 74 2f 43 6c 69 65 6e 74 2f 66 |home/qt/Client/f|
str data...
00000020 69 6c 65 2e 74 78 74 00 00 00 00 14 61 61 61 61 |ile.txt.....aaaa|
str data > <data len > <
00000030 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |aaaaaaaaaaaaaaaa|
data >