C语言实现将一个tar文件大小变大,并在最后一个文件末尾添加一个文件,插入后的tar文件能在Linux下解压。
时间: 2024-03-24 16:41:22 浏览: 192
C语言多文件创建与写入
修改tar文件大小并插入文件,需要进行以下步骤:
1. 打开tar文件,并读取其中的文件头信息;
2.要插入的文件的内容添加到tar文件中,记录文件头信息;
3. 修改tar文件中记录的所有文件的大小,以反映添加后的tar文件的大小;
4. 将所有文件头信息重新写入tar文件。
以下是C语言实现的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define BLOCK_SIZE 512
int main(int argc, char **argv)
{
if (argc < 3) {
printf("Usage: %s <tarfile> <file_to_insert>\n", argv[0]);
return 1;
}
int tar_fd = open(argv[1], O_RDWR);
if (tar_fd < 0) {
printf("Failed to open tarfile %s\n", argv[1]);
return 1;
}
int insert_fd = open(argv[2], O_RDONLY);
if (insert_fd < 0) {
printf("Failed to open file to insert %s\n", argv[2]);
return 1;
}
// 获取插入文件的大小和名称
struct stat st;
memset(&st, 0, sizeof(st));
if (fstat(insert_fd, &st) < 0) {
printf("Failed to get file size %s\n", argv[2]);
return 1;
}
int insert_size = st.st_size;
char *insert_name = strrchr(argv[2], '/') ? strrchr(argv[2], '/') + 1 : argv[2];
// 找到tar文件的结尾位置
off_t tar_size = lseek(tar_fd, 0, SEEK_END);
off_t tar_end = tar_size - (tar_size % BLOCK_SIZE) + BLOCK_SIZE;
// 计算新添加文件的大小和块数
int blocks_needed = insert_size / BLOCK_SIZE + (insert_size % BLOCK_SIZE ? 1 : 0);
int insert_blocks = blocks_needed + (blocks_needed % 2 ? 1 : 0);
int insert_size_padded = insert_blocks * BLOCK_SIZE;
// 调整tar文件的大小
if (ftruncate(tar_fd, tar_end + insert_size_padded) < 0) {
printf("Failed to resize tarfile\n");
return 1;
}
// 写入新文件的数据
char buffer[BLOCK_SIZE];
memset(buffer, 0, BLOCK_SIZE);
int bytes_read;
while ((bytes_read = read(insert_fd, buffer, BLOCK_SIZE)) > 0) {
write(tar_fd, buffer, BLOCK_SIZE);
}
// 写入新文件的文件头信息
memset(buffer, 0, BLOCK_SIZE);
sprintf(buffer, "%s", insert_name);
write(tar_fd, buffer, 100);
sprintf(buffer, "%07o", st.st_mode);
write(tar_fd, buffer, 8);
sprintf(buffer, "%07o", geteuid());
write(tar_fd, buffer, 8);
sprintf(buffer, "%07o", getegid());
write(tar_fd, buffer, 8);
sprintf(buffer, "%011o", insert_size);
write(tar_fd, buffer, 12);
sprintf(buffer, "%011o", time(NULL));
write(tar_fd, buffer, 12);
memset(buffer, ' ', 100);
write(tar_fd, buffer, 100);
// 写入新文件的填充块
if (insert_size_padded - insert_size > 0) {
memset(buffer, 0, BLOCK_SIZE);
write(tar_fd, buffer, insert_size_padded - insert_size);
}
// 重新写入所有文件的文件头信息
off_t pos = 0;
while (pos < tar_end) {
lseek(tar_fd, pos, SEEK_SET);
read(tar_fd, buffer, 100);
if (buffer[0] == '\0') {
break;
}
sscanf(buffer + 124, "%lo", &st.st_size);
lseek(tar_fd, pos, SEEK_SET);
sprintf(buffer + 124, "%011lo", st.st_size);
write(tar_fd, buffer, 100);
pos += (st.st_size / BLOCK_SIZE + (st.st_size % BLOCK_SIZE ? 1 : 0)) * BLOCK_SIZE;
}
close(tar_fd);
close(insert_fd);
return 0;
}
```
这个程序将tar文件大小调整为块大小的倍数,插入文件后添加必要的填充块,然后重新写入所有文件的文件头信息以反映新的tar文件大小。插入的新文件的文件头信息也被写入到tar文件中。注意,这个程序只支持tar文件格式,而不支持.tar.gz或其他压缩格式。
阅读全文