可以将std::对的std::矢量转换为字节数组
Possible to convert std::vector of std::pairs into a byte array?
我想知道是否可以将成对的向量转换为字节数组。
这里有一个创建成对向量的小例子:
int main(int argc, char *argv[])
{
PBYTE FileData, FileData2, FileData3;
DWORD FileSize, FileSize2, FileSize3;
/* Here I read 3 files + their sizes and fill the above variables. */
//Here I create the vector of std::pairs.
std::vector<std::pair<PBYTE, DWORD>> DataVector
{
{ FileData, FileSize }, //Pair contains always file data + file size.
{ FileData2, FileSize2 },
{ FileData3, FileSize3 }
};
std::cin.ignore(2);
return 0;
}
是否可以将这个矢量转换为字节数组(用于压缩和写入磁盘等)?
以下是我尝试过的,但我甚至没有得到正确的尺寸:
PVOID DataVectorArr = NULL;
DWORD DataVectorArrSize = DataVector.size() * sizeof DataVector[0];
if ((DataVectorArr = malloc(DataVectorArrSize)) != NULL)
{
memcpy(DataVectorArr, &DataVector[0], DataVectorArrSize);
}
std::cout << DataVectorArrSize;
//... Here I tried to write the DataVectorArr to disk, which obviously fails because the size isn't correct. I am not also sure if the DataVectorArr contains the DataVector now.
if (DataVectorArr != NULL) delete DataVectorArr;
足够的代码。这有可能吗,还是我做错了?如果我做错了,解决办法是什么?
问候,Okkaaj
编辑:如果不清楚我想做什么,请阅读以下内容(我之前评论过):
是的,我正在尝试将对的向量强制转换为PCHAR
或PBYTE
,这样我就可以使用WriteFile将其存储到磁盘上。存储后,我可以将其作为字节数组从磁盘中读取,并解析回成对的向量。这可能吗?我的想法来自于将struct
转换/强制转换为字节数组并返回(阅读更多内容:将结构转换为字节并返回结构),但我不确定用std::vector而不是结构是否可行。
去掉malloc
,并使用RAII进行此操作:
std::vector<BYTE> bytes;
for (auto const& x : DataVector)
bytes.insert(bytes.end(), x.first, x.first+x.second);
// bytes now contains all images buttressed end-to-end.
std::cout << bytes.size() << 'n';
为了避免潜在的慢车道调整大小,您可以先枚举大小计算,然后提前.reserve()
空间:
std::size_t total_len = 0;
for (auto const& x : DataVector)
total_len += x.second;
std::vector<BYTE> bytes;
bytes.reserve(total_len);
for (auto const& x : DataVector)
bytes.insert(bytes.end(), x.first, x.first+x.second);
// bytes now contains all images buttressed end-to-end.
std::cout << bytes.size() << 'n';
但是,如果您只想将这些文件连续转储到磁盘,那么为什么不简单地:
std::ofstream outp("outfile.bin", std::ios::out|std::ios::binary);
for (auto const& x : DataVector)
outp.write(static_cast<const char*>(x.first), x.second);
outp.close();
完全跳过中间人。
老实说,除非有充分的理由这样做,否则很可能您的DataVector最初只是一个std::vector< std::vector<BYTE> >
会更好。
更新
如果需要恢复,则不能仅按上述方式执行。缺少的最小工件是数据本身的描述。在这种情况下,描述是每个对段的实际长度。为了实现这一点,长度必须与数据一起存储。这样做是微不足道的,除非您还需要它可移植到平台独立性。
如果最后一句话让你扬起眉毛,那么考虑一下做这样简单的事情的问题:
std::ofstream outp("outfile.bin", std::ios::out|std::ios::binary);
for (auto const& x : DataVector)
{
uint64_t len = static_cast<uint64_t>(x.first);
outp.write(reinterpret_cast<const char *>(&len), sizeof(len));
outp.write(static_cast<const char*>(x.first), x.second);
}
outp.close();
好吧,现在你可以通过以下操作读取每个文件:
- 读取一个
uint64_t
以获得后面数据的字节长度 - 读取该长度的数据
但这也存在固有的问题。它根本不便携。读者平台的endian表示最好与作者的表示相匹配,否则就彻底失败了。为了适应这种限制,长度前导必须以独立于平台的方式编写,这是乏味的,也是序列化库及其协议首先退出的基本原因。
如果到目前为止你还没有猜到你在做什么以及你是如何做的,你可能想再读一遍。
- std::当在256字节边界上写入整数时,流的奇怪行为
- 使用 std::vector::reverse_iterator 将 int 序列化为字节向量?
- 如何将原始字节附加到 std::vector?
- std::ifstream::read 不会读取所有 512 字节,并设置 EOF 和失败位
- 如何在C++中将字节向量(std::vector<uint8_t>)转换为不同的uint32_t,uint16_t和uint8_t变量
- 如何将带有空字符的字节数组馈送到 std::iostream 中?
- Swig无法将python3的字节对象转换为std::string
- 如何从Little Endian UTF-16编码字节中获取C++std::string
- 比较存储在 std::string 中的数据中的字节数
- libc++ 的 std::basic_string 的 16 字节对齐模式背后的原因是什么?
- std::字符串到字符*而不切割字节
- std::memcmp 可以读取超过第一个差异的任何字节吗?
- std::字符串与字节缓冲区(C++的差异)
- 在 std::string 中使用非法的 UTF-8 八位字节作为分隔符
- 如何将字节从 std::ostream 流式传输到 std::vector<uint8_t>?
- 用字节初始化 char* 和 std::字符串
- std :: string的解密具有额外的填充字节
- 为什么标准库不以无锁的方式为 8 字节以下的结构实现 std::atomic?
- C++ 17 中的 std::byte 等同于 C# 中的字节
- 如何在需要老式的未签名炭的地方使用新的std ::字节类型