【问题标题】:Is readsome() appropriate to read binary data on Windows?readsome() 是否适合在 Windows 上读取二进制数据?
【发布时间】:2019-03-15 03:15:01
【问题描述】:

上下文:我正在尝试用 C++ 读取 PNG 图片的内容,以便稍后将其发送到我的 Android 应用程序。为此,我以二进制模式打开文件,按 512 字节的块读取其内容,然后将数据发送到应用程序。我在 Windows 上。

问题: 我使用 ifstream 实例和 readsome() 函数如下所示,它返回给我 512,这是什么我期待,因为我要求读取 512 个字节。但是,我的缓冲区中似乎远没有真正拥有 512 个字节,这让我感到困惑。当我逐步调试我的程序时,缓冲区中的字符数似乎是随机的,但绝不是预期的 512。

代码:

int currentByteRead = 0;
std::ifstream fl(imgPath.toStdString().c_str(), ios_base::binary);
fl.seekg( 0, std::ios::end );
int length = fl.tellg();

char *imgBytes = new char[512];

fl.seekg(0, std::ios::beg);
// Send the img content by blocks of 512 bytes
while(currentByteRead + 512 < length) {
    int nbRead = fl.readsome(imgBytes, 512); // nbRead is always set to 512 here

    if(fl.fail()) {
        qDebug() << "Error when reading file content";
    }

    sendMessage(...);
    currentByteRead += 512;
    imgBytes = new char[512];
}

// Send the remaining data
int nbRemainingBytes = length - currentByteRead;
fl.readsome(imgBytes, nbRemainingBytes);
sendMessage(...);
fl.close();
currentByteRead += nbRemainingBytes;

我一开始得到的长度是正确的,似乎没有错误。但好像在 readsome() 调用期间并非所有数据都复制到缓冲区中。

问题:我对 readsome() 函数有误解吗?是否有与 Windows 相关的东西导致这种行为?有没有更合适的方式进行?

【问题讨论】:

  • 你肯定不是想分配new char[512]每次
  • 为什么你认为你的缓冲区“远非 512 字节”?
  • 你说得对,我将实现更改为使用 char 向量的更简洁的代码。要回答您的第二个问题,缓冲区似乎只包含字符,直到找到第一个 '\n'。 readsome() 每次仍然返回 512。我将使用我现在拥有的代码编辑我的帖子,因为它可以工作。
  • 同时,原代码中的nbRead是什么?你从不使用它。
  • 我按照您的建议发布了答案。 nbRead 只是用来存储readsome 函数的返回值。它仅在第一个实现中有助于调试目的。为了清楚起见,我编辑了代码。

标签: c++ iostream


【解决方案1】:

我终于找到了一种方法来做我想做的事,正如 David Herring 所建议的,我将把我的答案放在这里。

我对这个问题的看法:如果我使用 std::ifstream::pos_type 变量而不是 int,则正确的数字字节数被读取并放入缓冲区。使用 int 时情况并非如此,就好像字符只写入缓冲区直到给定(随机?)点。我不确定为什么会发生这种行为。我的猜测是我遇到了 '\n' 字符的问题,但缓冲区最终内容的随机性对我来说仍然不清楚。

更正:这是我最终达到的工作代码。从这个开始,我就可以做我想做的事了。

std::ifstream ifs(imgPath.toStdString().c_str(), std::ios::binary|std::ios::ate);
std::ifstream::pos_type pos = ifs.tellg();
int length = ifs.tellg();
std::vector<char>  result(pos);
ifs.seekg(0, std::ios::beg);
ifs.read(result.data(), pos);
ifs.close();

我希望这对其他人有所帮助。谢谢大卫的建议。

【讨论】:

    猜你喜欢
    • 2014-09-19
    • 1970-01-01
    • 2012-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-08
    • 2018-03-08
    • 2017-07-10
    相关资源
    最近更新 更多