c++ - 让一个`std::vector` 从 `std::string` 窃取内存
问题描述
假设我们有std::string s
一个原始数据缓冲区,但我们想要std::vector<uint8_t> v
。缓冲区长度以百万计。有没有一种简单的方法可以让v
窃取s
内存从而避免复制缓冲区?
就像std::vector<uint8_t>::vector(std::string&&)
会做的那样,但以某种方式从 STL 外部进行。
或者,是否有可能v
从std::stringstream ss
与效率一样高的操作中获得ss.str()
?
解决方案
好的,那里有很多评论,让我们尝试将一些东西放在一起,因为我需要练习并且可能会获得一些积分[更新:没有:(]。
我对“现代 C++”还很陌生,所以请在找到时接受它。可能需要到 C++17,我没有仔细检查过。任何批评都非常受欢迎,但我更愿意编辑我自己的帖子。请记住,在阅读本文时,OP真正想要做的是从文件中读取他的字节。谢谢。
更新:根据@Deduplicator 下面的评论,调整以处理文件大小在调用stat()
和调用之间发生变化的情况fread()
......随后替换fread
为std::ifstream
,我想我们现在就在那里。
#include <string>
#include <vector>
#include <optional>
#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
using optional_vector_of_char = std::optional <std::vector <char>>;
// Read file into a std::optional <std::vector <char>>.
// Now handles the file size changing when we're not looking.
optional_vector_of_char SmarterReadFileIntoVector (std::string filename)
{
for ( ; ; )
{
struct stat stat_buf;
int err = stat (filename.c_str (), &stat_buf);
if (err)
{
// handle the error
return optional_vector_of_char (); // or maybe throw an exception
}
size_t filesize = stat_buf.st_size;
std::ifstream fs;
fs.open (filename, std::ios_base::in | std::ios_base::binary);
if (!fs.is_open ())
{
// handle the error
return optional_vector_of_char ();
}
optional_vector_of_char v (filesize + 1);
std::vector <char>& vecref = v.value ();
fs.read (vecref.data (), filesize + 1);
if (fs.rdstate () & std::ifstream::failbit)
{
// handle the error
return optional_vector_of_char ();
}
size_t bytes_read = fs.gcount ();
if (bytes_read <= filesize) // file same size or shrunk, this code handles both
{
vecref.resize (bytes_read);
vecref.shrink_to_fit ();
return v; // RVO
}
// File has grown, go round again
}
}
int main ()
{
optional_vector_of_char v = SmarterReadFileIntoVector ("abcde");
std::cout << std::boolalpha << v.has_value () << std::endl;
}
现场演示。当然,没有可读取的实际文件,所以...
另外:您是否考虑过编写自己的简单容器来映射文件视图?只是一个想法。
推荐阅读
- python - 如何对列表的元素进行分组?
- haskell - 在哪里可以找到 Stack 的 package.yaml 的对应名称列表,从 Haskell 代码中的 Import 语句中了解包名称
- python - 给定数据集的傅里叶变换和滤波
- javascript - 使用 DOM 操作传递具有应用样式的元素
- html - 如何在白色背景的图像顶部添加导航栏
- python - 为什么 Pandas 中的替换功能会引发 SettingWithCopyWarning?
- reactjs - 我如何使用带有'django'的反应路由器
- html - RobotFramework:未找到带有定位器的链接/列表
- asp.net-core - 如何在 Controller 中调用 DotNet Core API HealthCheck 探针,而不是在 Ctartup.cs 中设置
- python - 在单行中总结熊猫数据框