简体   繁体   English

可以将std :: pairs的std :: vector转换为字节数组吗?

[英]Possible to convert std::vector of std::pairs into a byte array?

I am wondering if it is possible to convert vector of pairs into a byte array. 我想知道是否有可能将向量对转换为字节数组。

Here's a small example of creating the vector of pairs: 这是创建对向量的一个小示例:

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;
}

Is it possible to convert this vector into a byte array (for compressing, and writing to disk, etc)? 是否可以将此向量转换为字节数组(用于压缩和写入磁盘等)?

Here is what I tried, but I didn't get even the size correctly: 这是我尝试过的方法,但大小不正确:

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;

Enough code. 足够的代码。 Is is it even possible, or am I doing it wrong? 可能吗,还是我做错了? If I am doing it wrong, what would be the solution? 如果我做错了,那该怎么办?

Regards, Okkaaj 问候,Okkaaj

Edit: If it's unclear what I am trying to do, read the following (which I commented earlier): 编辑:如果不清楚我要做什么,请阅读以下内容(我之前评论过):

Yes, I am trying to cast the vector of pairs to a PCHAR or PBYTE - so I can store it to disk using WriteFile. 是的,我正在尝试将向量对转换为PCHARPBYTE这样我可以使用WriteFile将其存储到磁盘。 After it is stored, I can read it from disk as byte array, and parse back to vector of pairs. 存储之后,我可以将它作为字节数组从磁盘读取,然后解析回成对的向量。 Is this possible? 这可能吗? I got the idea from converting / casting struct to a byte array and back(read more from here: Converting struct to byte and back to struct ) but I am not sure if this is possible with std::vector instead of structures. 我从将struct转换/转换为字节数组然后返回的想法(从这里阅读更多: 将结构转换为字节然后返回结构 ),但是我不确定是否可以使用std :: vector而不是结构来实现。

Get rid of the malloc and make use of RAII for this: 摆脱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';

To avoid potential resize slow-lanes, you can enumerate the size calculation first, then .reserve() the space ahead of time: 为避免潜在的调整大小慢速通道,您可以先枚举大小计算,然后.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';

But if all you want to do is dump these contiguously to disk, then why not simply: 但是,如果您要做的只是将这些连续地转储到磁盘上,那为什么不简单地:

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();

skipping the middle man entirely. 完全跳过中间人。

And honestly, unless there is a good reason to do otherwise, it is highly likely your DataVector would be better off as simply a std::vector< std::vector<BYTE> > in the first place. 和诚实,除非有一个很好的理由不这样做,它有可能你的dataVector中会更好地成为一个简单std::vector< std::vector<BYTE> >摆在首位。


Update 更新资料

If recovery is needed, you can't just do this as above. 如果需要恢复 ,则不能仅执行上述操作。 The minimal artifact that is missing is the description of the data itself. 缺少的最小工件是数据本身的描述。 In this case the description is the actual length of each pair segment. 在这种情况下,描述是每个对段的实际长度 To accomplish that the length must be stored along with the data. 为此,必须将长度与数据一起存储。 Doing that is trivial unless you also need it portable to platform-independence. 除非您还需要将其移植到平台无关的地方,否则这样做是微不足道的。

If that last sentence made you raise your brow, consider the problems with doing something as simple as this: 如果最后一句话让您抬起眉头,请考虑执行以下简单操作所带来的问题:

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();

Well, now you can read each file by doing this: 好了,现在您可以通过执行以下操作来读取每个文件:

  • Read a uint64_t to obtain the byte length of the data to follow 读取uint64_t以获取要跟随的数据的字节长度
  • Read the data of that length 读取该长度的数据

But this has inherent problems. 但这具有内在的问题。 It isn't portable at all. 它根本不是便携式的。 The endian-representation of the reader's platform had better match that of the writer, or this is utter fail. 读者平台的字节序表示最好与作者平台的字节序匹配,否则这将完全失败。 To accommodate this limitation the length preamble must be written in a platform-independent manner, which is tedious and a foundational reason why serialization libraries and their protocols exit in the first place. 为了适应此限制,必须以与平台无关的方式编写长度前导,这是繁琐的工作,也是序列化库及其协议首先退出的根本原因。

If you haven't second-guessed what you're doing and how you're doing it by this point, you may want to read this again. 如果您现在还没有对自己在做什么和如何做的猜测,您可能想再次阅读。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM