Is it possible to delete N bytes from begining of a file in C?
N is 30 bytes only.
I can't copy a file because they are very large (sometimes even 100 of GBs)
Is it possible to delete N bytes from begining of a file in C?
N is 30 bytes only.
I can't copy a file because they are very large (sometimes even 100 of GBs)
On Linux you can create a loopback device pointing to an offset within another file. Here is such an example from unix.stackexchange:
#!/bin/bash
for ((i=0;i<10000;i++)); do
printf "%7d\n" $i
done >/var/tmp/file
losetup -v -f -o 512 --sizelimit 512 /var/tmp/file
losetup -a
head -2 /var/tmp/file
echo ...
tail -2 /var/tmp/file
echo ===
head -2 /dev/loop0
echo ...
tail -2 /dev/loop0
printf "I was here" > /dev/loop0
grep here /var/tmp/file
losetup -d /dev/loop0
output:
loop device: /dev/loop0
/dev/loop0: [0808]:136392 (/var/tmp/file), offset 512, size 512
0
1
...
9998
9999
===
64
65
...
126
127
I was here 65
You can't delete 30 bytes from the beginning of the file, but nothing stops you from overwriting the file (at least, on most Unix filesystems). This amounts to a copy in terms of the amount of time it takes, but it doesn't use up your free disk space.
Here's a little function which might help, although I didn't test it thoroughly.
One warning: it used to be the case that off_t was a 32-bit signed integer, and therefore pread, pwrite and ftruncate could not be used on files larger than 2GB. On Linux, this is no longer the case. However, it may be necessary to use pread64, pwrite64 and ftruncate64. Don't try this on a really large file you care about until you've verified that it actually works on your OS.
int fshift(int fd, off_t to, off_t from) {
if (from <= to) {
fprintf(stderr, "%s\n", "Unimplemented: fshift can only shift left");
errno = ERANGE;
return -1;
}
char buffer[BUFFER_SIZE];
for (;;) {
ssize_t n_read = pread(fd, buffer, BUFFER_SIZE, from);
if (n_read < 0) {
int tmp = errno;
perror("fshift: could not read file");
errno = tmp;
return -1;
}
from += n_read;
if (n_read == 0) {
int rc = ftruncate(fd, to);
if (rc < 0) {
int tmp = errno;
perror("fshift: could not truncate file");
errno = tmp;
}
return rc;
}
for (char* p = buffer, *lim = &buffer[n_read]; p < lim;) {
ssize_t n_write = pwrite(fd, p, lim - p, to);
if (n_write < 0) {
int tmp = errno;
perror("fshift: could not write file");
errno = tmp;
return -1;
}
p += n_write;
to += n_write;
}
}
}