gpt4 book ai didi

c++ - 使用 boost::mapped_region 生成文件以进一步写入?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:03:47 25 4
gpt4 key购买 nike

我需要创建并写入一个内存映射文件。有时需要增大文件。

我创建了以下小测试,我创建了一个文件,使用 boost::mapped_region 映射它并写入它。

这一切都按预期工作:

#include <fstream>
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>

namespace bip = boost::interprocess;

void createFile(const char* fn, std::uint64_t num)
{
std::filebuf fbuf;
fbuf.open(fn, std::ios_base::out|std::ios_base::binary|std::ios_base::trunc);

const std::uint64_t size = sizeof(std::uint64_t) * (num + 1);

fbuf.pubseekoff(size - 1, std::ios_base::beg);
fbuf.sputc(0);
fbuf.close();
}

void writeToFile(const char* fn, std::uint64_t pos, std::uint64_t val)
{
bip::file_mapping fm(fn, bip::read_write);
bip::mapped_region rg(fm, bip::read_write);

std::uint64_t* p = reinterpret_cast<std::uint64_t*>(rg.get_address());

*p = std::max(*p, pos); // store max num values
*(p + pos) = val; // write value into position
}

int main ()
{
const char* fn = "/tmp/test.dat";

createFile(fn, 3);
writeToFile(fn, 1, 0x1111111111111111);
writeToFile(fn, 2, 0x2222222222222222);
writeToFile(fn, 3, 0x3333333333333333);

return 0;
}

运行这个程序会产生一个预期的输出文件,当我转储它的内容时,我可以看到正确写入其中的值:

$ xxd -p /tmp/test.dat 
030000000000000011111111111111112222222222222222333333333333
3333

但是,现在我想调整文件大小,以便可以在末尾写入额外的数据。

我添加了以下函数,growFile(它使用 ios_base::app,正如下面 timrau 所建议的)

void growFile(const char* fn, std::uint64_t num)
{
std::filebuf fbuf;
fbuf.open(fn, std::ios_base::out|std::ios_base::binary|std::ios_base::app);

const std::uint64_t size = sizeof(std::uint64_t) * (num + 1);

fbuf.pubseekoff(size - 1, std::ios_base::beg);
fbuf.sputc(0);
fbuf.close();
}

我现在在增加文件后添加更多值:

int main ()
{
const char* fn = "/tmp/test.dat";

createFile(fn, 3);
writeToFile(fn, 1, 0x1111111111111111);
writeToFile(fn, 2, 0x2222222222222222);
writeToFile(fn, 3, 0x3333333333333333);

growFile(fn, 6);
writeToFile(fn, 4, 0x4444444444444444);
writeToFile(fn, 5, 0x5555555555555555);
writeToFile(fn, 6, 0x6666666666666666);

return 0;
}

当我转储文件时,它丢失了大部分新值。

$ xxd -p /tmp/test.dat 
060000000000000011111111111111112222222222222222333333333333
333344

请注意,如果我不增加文件,而只是在最初使用足够的空间创建它,它会按预期工作:

int main ()
{
const char* fn = "/tmp/test.dat";

createFile(fn, 6);
writeToFile(fn, 1, 0x1111111111111111);
writeToFile(fn, 2, 0x2222222222222222);
writeToFile(fn, 3, 0x3333333333333333);
writeToFile(fn, 4, 0x4444444444444444);
writeToFile(fn, 5, 0x5555555555555555);
writeToFile(fn, 6, 0x6666666666666666);

return 0;
}

当我转储文件时,所有值都在那里:

$ xxd -p /tmp/test.dat 
060000000000000011111111111111112222222222222222333333333333
3333444444444444444455555555555555556666666666666666

我如何在创建文件后增大我的文件,以便我可以进一步写入其初始大小?

最佳答案

我在 coliru 上玩了另一个

您必须打开文件进行读/写 - 相当于::fopen(..., "r+")

这些选项都有效:

void resizeFile(const char* fn)
{
constexpr auto offset = sizeof(std::uint64_t) * 6 - 1;

/*
FILE* fp = ::fopen(fn, "r+");
::fseek(fp, offset, SEEK_SET);
::fputc(0, fp);
::fclose(fp);
*/

/*
std::fstream f;
f.exceptions(std::ios::failbit | std::ios::badbit);
f.open(fn, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
f.seekp(offset, std::ios_base::beg);
f.put(0);
f.flush();
*/

std::filebuf fbuf;
fbuf.open(fn, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
fbuf.pubseekoff(offset, std::ios_base::beg);
fbuf.sputc(0);
fbuf.close();
}

http://coliru.stacked-crooked.com/a/ae224032dd036639

关于c++ - 使用 boost::mapped_region 生成文件以进一步写入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52322855/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com