You can memory map the file, and shift the contents:
int main() {
prepend("data.dat", { 1,2,3,4,5,6 });
}
Implemented with 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());
}
BONUS
Alternative version without the use of Boost (or, actually C++ at all, outside the static_cast
):
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);
}