高效从DataReader读取一些字节?

时间:2014-10-28 12:59:33

标签: windows-phone-8 datareader c++-cx

我有一个带有ANSI字符串的流。它以字节长度为前缀。如何将其读入std::string

类似的东西:

short len = reader.readInt16();
char[] result = reader.readBytes(len); // ???
std::string str = std::copy(result, result + len);

但没有方法readBytes(int)

附带问题:一次只能从readByte()一个字节读取DataReader是否很慢?

1 个答案:

答案 0 :(得分:3)

根据MSDN,DataReader :: ReadBytes存在并且您正在寻找:http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.streams.datareader.readbytes

它需要Platform::Array<unsigned char>作为参数,大概你会使用前缀长度初始化,返回时将包含你的字节。从那里开始构建所需的std::string是一个繁琐而直接的过程。

基本用法看起来像这样(道歉,目前在Mac上,所以精确的语法可能有点偏离):

auto len = reader->ReadInt16();
auto data = ref new Platform::Array<uint8>(len);
reader->ReadBytes(data);

// now data has the bytes you need, and you can make a string with it

请注意,上面的代码生产就绪 - 绝对可能reader没有足够的数据缓冲,因此您需要reader.LoadAsync(len)和创建一个继续来处理数据可用时的数据。尽管如此,希望这足以让你前进。

修改

刚刚注意到你的问题。简短的回答是,是的,一次读取一个字节要慢很多,因为这样做的工作要多得多。

答案很长:考虑每个字节的内容:

  1. 发生函数调用 - 堆栈帧分配
  2. 从缓冲区读取字节的一些逻辑发生
  3. 函数返回 - 弹出堆栈帧,推送结果,控制返回
  4. 您接受该字节,然后将其推送到std::string,偶尔会导致动态重新分配(除非您已经str.resize(len),否则)
  5. 在所有发生的事情中,动态重新分配是真正的性能杀手。话虽这么说,如果你有很多字节,函数调用的工作将主导读取字节的工作。

    现在,考虑一次读取所有字节时会发生什么:

    1. 发生函数调用 - 堆栈帧,推送结果数组
    2. (在所有请求数据存在的快乐路径中)从内部缓冲区到预分配数组的memcpy
    3. 返回
    4. memcpy到字符串
    5. 这当然要快得多 - 你的分配在读取的字节数方面是不变的,函数调用的数量也是如此。