Truncating the first 100MB of a file in linux

CheeHow picture CheeHow · Aug 6, 2013 · Viewed 18.3k times · Source

I am referring to How can you concatenate two huge files with very little spare disk space?

I'm in the midst of implementing the following:

  1. Allocate a sparse file of the combined size.
  2. Copy 100Mb from the end of the second file to the end of the new file.
  3. Truncate 100Mb of the end of the second file
  4. Loop 2&3 till you finish the second file (With 2. modified to the correct place in the destination file).
  5. Do 2&3&4 but with the first file.

I would like to know if is there anyone there who are able to "truncate" a given file in linux? The truncation is by file size, for example if the file is 10GB, I would like to truncate the first 100MB of the file and leave the file with remaining 9.9GB. Anyone could help in this?

Thanks

Answer

Sunding Wei picture Sunding Wei · Aug 1, 2014

Answer, now this is reality with Linux kernel v3.15 (ext4/xfs)

Read here http://man7.org/linux/man-pages/man2/fallocate.2.html

Testing code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>

#ifndef FALLOC_FL_COLLAPSE_RANGE
#define FALLOC_FL_COLLAPSE_RANGE        0x08
#endif

int main(int argc, const char * argv[])
{
    int ret;
    char * page = malloc(4096);
    int fd = open("test.txt", O_CREAT | O_TRUNC | O_RDWR, 0644);

    if (fd == -1) {
        free(page);
        return (-1);
    }

    // Page A
    printf("Write page A\n");
    memset(page, 'A', 4096);
    write(fd, page, 4096);

    // Page B
    printf("Write page B\n");
    memset(page, 'B', 4096);
    write(fd, page, 4096);

    // Remove page A
    ret = fallocate(fd, FALLOC_FL_COLLAPSE_RANGE, 0, 4096);
    printf("Page A should be removed, ret = %d\n", ret);

    close(fd);
    free(page);

    return (0);
}