通过QDataStream和QTcpSocket读取和发送文件

时间:2011-10-04 23:27:23

标签: qt qtcpsocket qfile

我的问题是变量内容始终为空。 这是我的代码:

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

内容始终为空

感谢您的帮助

1 个答案:

答案 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                                 >