写入文件中的某个位置而不会丢失文件内容

时间:2015-01-01 13:00:22

标签: c++

在C ++中,我想逐字节地打开和写入一些文件。但是当我打开一个文件并写一些东西时,之前的内容就丢失了。如何将新数据添加到文件的开头并转换以前的内容。是否可能?怎么做?

ofstream file;
file.open("test.daf",app);
file.seekp(0);
file << 'A';

2 个答案:

答案 0 :(得分:2)

您可以对内存映射文件,并移动内容:

int main() {
    prepend("data.dat", { 1,2,3,4,5,6 });
}

使用boost实现:

<强> Live On Coliru

void prepend(path fname, std::vector<uint8_t> const& prepend_data)
{
    using namespace boost::iostreams;
    auto size    = file_size(fname);
    auto resized = size + prepend_data.size();

    resize_file(fname, resized);
    mapped_file mf(fname.native());

    std::rotate(mf.data(), mf.data() + size, mf.data() + resized);
    std::copy(prepend_data.begin(), prepend_data.end(), mf.data());
}

奖金

static_cast之外不使用Boost(或actually C++ at all)的替代版本:

<强> Live On Coliru

#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

void prepend(const char* fname, char const* prepend_data, size_t n)
{
    struct stat s;
    stat(fname, &s);
    size_t size    = s.st_size;
    size_t resized = size + n;

    truncate(fname, resized);
    int fd = open(fname, O_RDWR);
    char* mapped_file = static_cast<char*>(mmap(NULL, resized, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));

    memmove(mapped_file + n, mapped_file, size);
    memcpy (mapped_file, prepend_data, n);
}

int main() {
    char const to_prepend[] = { 1,2,3,4,5,6 };
    prepend("data.dat", to_prepend, sizeof to_prepend);
}

答案 1 :(得分:-1)

文件无法正常工作,如字符串等。

您需要做的是加载文件的内容,将先前的内容放入文件中,然后在此之后放回文件的旧内容。

根据您的文件大小或性能,您可能只是将整个文件加载到一个字符串中(如果它是所有文本而不是二进制文件)并将该字符串附加到您的字符串上,然后将完整的字符串写入该文件。 示例:string out_data = your_data + file_data;

或像这样的二进制文件:

std::fstream f;
f.open ("test.daf", std::fstream::in | std::fstream::out | std::fstream::app);
f.seekg (0, f.end);
int length = f.tellg();
f.seekg (0, f.beg);

char * buffer = new char [length];
f.read (buffer,length);
f << 'A'; // Like you wanted it

// Or more binary data
char data[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
f.write(data, 10);

f.write(buffer, length); // Finally put back the original content

f.close();

以上未经过测试,可能不是最佳解决方案。出于性能原因,我不会在程序中多次使用它。