我正在使用带有C ++的libcurl(HTTP传输库)并尝试从远程HTTP服务器下载文件。下载文件时,多次调用我的回调函数(例如每10 kb)向我发送缓冲区数据。
基本上我需要类似“字符串缓冲”的东西,这是一种将char
缓冲区附加到现有字符串的数据结构。在C中,我分配(malloc
)一个char*
然后作为新的缓冲区,我realloc
然后memcpy
,以便我可以轻松地将我的缓冲区复制到调整大小的数组。
在C中,有多种解决方案可以实现这一目标。
malloc
,realloc
,memcpy
,但我很确定它们不会在C ++中使用。vector<char>
。stringstream
。我的用例是,我会一次附加几千个项目(char
s),在完成所有项目(下载完成)后,我会立即阅读所有项目。但是我将来可能需要像seek
这样的选项(在阵列解决方案(1)中很容易实现),但现在它的优先级很低。
我应该使用什么?
答案 0 :(得分:1)
我会去stringstream
。只需在收到数据时插入即可,当您完成后,您可以从中提取完整的std::string
。我不明白你为什么要seek
进入数组?无论如何,如果您知道块大小,则可以计算相应块的字符串中的位置。
答案 1 :(得分:1)
我不确定是否有人会同意这一点,但对于该用例,我实际上会使用链表,每个节点包含使用new
分配的任意大的char数组。我的理由是:
如果通过列表寻求成为优先事项,这不会起作用。如果最终不是很多数据,我老实说认为矢量会很好,而不是 最有效的结构。
答案 2 :(得分:1)
如果您只需要附加char缓冲区,您也可以使用std::string
和成员函数append
。最重要的是stringstream
为您提供了格式,功能,因此您可以添加数字,填充等,但是根据您的说明,您似乎不需要。
答案 3 :(得分:1)
我想我会使用deque<char>
。与vector
相同的接口,矢量可以做,但是每次附加超出其现有容量时,矢量需要复制整个数据。增长是指数级的,但您仍然期望重新分配log N
,其中N
是您追加的相等大小的数据块的数量。 Deque不会重新分配,因此在向量需要多次重新分配的情况下,它是首选容器。
假设回调被传递了char*
缓冲区和长度,那么复制和附加数据的代码就足够简单了:
mydeque.insert(mydeque.end(), buf, buf + len);
如果你想要一个字符串,最后得到一个字符串:
std::string mystring(mydeque.begin(), mydeque.end());
我不完全确定seek
的含义,但显然deque
可以通过索引或迭代器访问,与vector
相同。
另一种可能性是,如果您希望在下载开始时使用内容长度,则可以在启动之前使用vector
和reserve()
足够的空间来存储数据,从而避免再分配。这取决于您正在进行的HTTP请求以及哪些服务器,因为一些HTTP响应将使用分块编码,并且不会预先提供大小。
答案 4 :(得分:0)
我会使用vector<char>
。但是他们的所有工作都会有所帮助,所以你的问题确实是风格问题,而且那里没有明确的答案。
答案 5 :(得分:0)
创建您自己的Buffer
类以抽象出存储的详细信息。如果我是你,我可能会基于std::vector<char>
实现缓冲区。