是否可以从 C 中的文件开头删除 N 个字节?
N 仅为 30 个字节。
我无法复制文件,因为它们非常大(有时甚至 100 GB)
在 Linux 上,您可以创建指向另一个文件中的偏移量的环回设备。这是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
输出:
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
您不能从文件开头删除 30 个字节,但没有什么能阻止您覆盖文件(至少,在大多数 Unix 文件系统上)。就其花费的时间而言,这相当于一个副本,但它不会耗尽您的可用磁盘空间。
这里有一个可能会有所帮助的小功能,尽管我没有彻底测试它。
一个警告:它曾经off_t
是一个 32 位有符号整数,因此 pread、pwrite 和 ftruncate 不能用于大于 2GB 的文件。在 Linux 上,情况不再如此。但是,可能需要使用 pread64、pwrite64 和 ftruncate64。在您确认它确实可以在您的操作系统上运行之前,不要在您关心的非常大的文件上尝试此操作。
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;
}
}
}