是否可以从C?
中的文件开头删除N个字节N仅为30个字节。
我无法复制文件,因为它们非常大(有时甚至是100 GB)
答案 0 :(得分:2)
在Linux上,您可以创建指向另一个文件中的偏移量的环回设备。来自unix.stackexchange的Here is such an example:
#!/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
答案 1 :(得分:1)
你不能从文件的开头删除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;
}
}
}