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

发布于 2024-12-07 23:43:27 字数 667 浏览 1 评论 0原文

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

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

内容始终为空

感谢您的帮助

My problem is that the variable content is always empty.
Here is my code:

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);

Output :

File opened

content is always empty

thanks for your help

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晌融 2024-12-14 23:43:27

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  |[email protected]...../|
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  |[email protected]...../|
          <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                                 >

content is not empty, but if you interpret it as a C-style 0-terminated string, it will appear to be empty.

When you write:

out.device()->seek(0);
out << static_cast<quint16>(content.size());

This will set the first two bytes of content to content.size() in big endian format (this is the default). So if content.size() is less than 255, the first byte of content.constData() will be 0 ('\0'). Any attempt to print constData() with a function that expects a C-style string will output nothing since your "string" starts with the "end-of-string" marker.

If you want to see the full contents of content, you should print all its chars separately and use something like hexdump to view the raw data.

Here's what I get if I do this instead of qDebug() << content.constData(); :

for (int i=0; i<content.size(); i++) {
    std::cout << content.constData()[i];
}

Output when run (the file contains just 20 'a' chars):

 $ ./qt | hexdump -C
00000000  00 40 00 00 00 05 66 69  6c 65 00 00 00 00 19 2f  |[email protected]...../|
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

If I had used:

std::cout << content.constData();

There would have been no output because of that very first 0 char.

If your data is longer, and the size of content is bigger than 255, the first char will no longer be 0, but you'll print two characters of garbage and nothing else because Qt serializes QString (and most other types) by first writing its length (32bit here), then its contents. Since its in big endian notation, the first byte has a very high chance of being 0.

Annotated output:

00000000  00 40 00 00 00 05 66 69  6c 65 00 00 00 00 19 2f  |[email protected]...../|
          <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                                 >
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文