C语言将新的文件插入到tar文件后,解压tar文件没有显示新插入的文件
时间: 2024-03-25 11:38:10 浏览: 21
这个问题可能是由于您将新文件插入到tar文件之后,未重新生成tar索引文件导致的。tar文件中有一个索引文件,它记录了tar文件中所有文件的名称和位置信息。如果您将新文件插入到tar文件中,但未更新索引文件,那么解压缩程序将无法找到新插入的文件。
解决这个问题的方法是使用tar命令重新生成索引文件。可以使用以下命令:
```tar -cvf archive.tar newfile
tar -uvf archive.tar
tar -tvf archive.tar
```
第一条命令将新文件插入到tar文件中。第二条命令将更新索引文件。第三条命令将列出tar文件中的所有文件,包括新插入的文件。
相关问题
C语言实现向tar文件中插入一个新的文件,给新的文件添加文件头,并且将tar文件解压后能显示新插入的文件
要向tar文件中插入一个新的文件并添加文件头,可以按照以下步骤实现:
1. 打开tar文件,并将文件指针移动到文件末尾,准备插入新文件。
```c
FILE *tar_file = fopen("example.tar", "ab"); // 打开tar文件,并将文件指针移动到文件末尾
```
2. 打开要插入的新文件,并读取文件内容和文件大小。
```c
char *filename = "newfile.txt";
FILE *new_file = fopen(filename, "rb"); // 打开要插入的新文件
// 获取新文件的大小
fseek(new_file, 0, SEEK_END);
long new_file_size = ftell(new_file);
fseek(new_file, 0, SEEK_SET);
// 读取新文件的内容
char *new_file_data = (char *)malloc(new_file_size);
fread(new_file_data, 1, new_file_size, new_file);
```
3. 创建一个tar头部结构体,并将文件名、文件大小等信息填入。
```c
struct tar_header {
char name[100];
char mode[8];
char uid[8];
char gid[8];
char size[12];
char mtime[12];
char checksum[8];
char type;
char linkname[100];
char ustar[6];
char owner[32];
char group[32];
char major[8];
char minor[8];
char prefix[155];
};
// 填写tar头部结构体
struct tar_header header;
strcpy(header.name, filename);
sprintf(header.mode, "%07o", 0644); // 文件访问权限
sprintf(header.uid, "%07o", 0); // 用户ID
sprintf(header.gid, "%07o", 0); // 组ID
sprintf(header.size, "%011o", new_file_size); // 文件大小
sprintf(header.mtime, "%011o", time(NULL)); // 上次修改时间
memset(header.checksum, ' ', 8); // 校验和,先填充空格
header.type = '0'; // 普通文件类型
memset(header.linkname, '\0', 100);
strcpy(header.ustar, "ustar ");
memset(header.owner, '\0', 32);
memset(header.group, '\0', 32);
memset(header.major, '\0', 8);
memset(header.minor, '\0', 8);
memset(header.prefix, '\0', 155);
```
4. 计算tar头部结构体中的校验和,并将新文件和tar头部结构体写入tar文件。
```c
// 计算校验和
unsigned int checksum = 0;
char *header_data = (char *)&header;
for (int i = 0; i < sizeof(header); i++) {
checksum += header_data[i];
}
char checksum_str[8];
sprintf(checksum_str, "%07o", checksum);
memcpy(header.checksum, checksum_str, 7);
// 将tar头部结构体写入tar文件
fwrite(&header, sizeof(header), 1, tar_file);
// 将新文件数据写入tar文件
fwrite(new_file_data, new_file_size, 1, tar_file);
```
5. 关闭文件并释放内存。
```c
fclose(tar_file); // 关闭tar文件
fclose(new_file); // 关闭新文件
free(new_file_data); // 释放内存
```
这样就完成了向tar文件中插入新文件并添加文件头的操作。在解压缩tar文件时,只要解压缩程序支持tar格式,并且正确读取tar头部结构体中的信息,就可以正确显示新插入的文件。
C语言实现tar文件的打包
在C语言中,可以使用libtar库来实现tar文件的打包。下面是一个简单的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <utime.h>
#include <tar.h>
int create_tar(const char *filename, const char *files[], int count) {
int fd;
size_t i, bytes_written;
struct stat stat_buf;
struct utimbuf time_buf;
char header_buf[T_BLOCKSIZE];
tar_header_t *header = (tar_header_t *) header_buf;
memset(header_buf, 0, T_BLOCKSIZE);
header->typeflag = REGTYPE;
for (i = 0; i < count; ++i) {
if (stat(files[i], &stat_buf) != 0) {
perror("stat");
return -1;
}
strncpy(header->name, files[i], T_NAMESIZE);
snprintf(header->size, T_SIZESIZE, "%011lo", (unsigned long) stat_buf.st_size);
snprintf(header->mode, T_MODESIZE, "%07o", stat_buf.st_mode & 07777);
snprintf(header->mtime, T_MTIMELEN, "%011lo", (unsigned long) stat_buf.st_mtime);
snprintf(header->uid, T_UIDSIZE, "%07o", stat_buf.st_uid);
snprintf(header->gid, T_GIDSIZE, "%07o", stat_buf.st_gid);
snprintf(header->magic, T_MAGICSIZE, "%s", TMAGIC);
snprintf(header->version, T_VERSIONSIZE, "%s", TVERSION);
snprintf(header->uname, T_UNAMESIZE, "%s", "");
snprintf(header->gname, T_GNAMESIZE, "%s", "");
snprintf(header->devmajor, T_DEVSIZE, "%s", "");
snprintf(header->devminor, T_DEVSIZE, "%s", "");
if ((fd = open(files[i], O_RDONLY)) == -1) {
perror("open");
return -1;
}
bytes_written = write(1, header_buf, T_BLOCKSIZE);
if (bytes_written != T_BLOCKSIZE) {
perror("write");
return -1;
}
bytes_written = 0;
while (bytes_written < stat_buf.st_size) {
bytes_written += sendfile(1, fd, NULL, stat_buf.st_size);
if (bytes_written == -1) {
perror("sendfile");
return -1;
}
}
close(fd);
time_buf.actime = stat_buf.st_atime;
time_buf.modtime = stat_buf.st_mtime;
if (utime(files[i], &time_buf) != 0) {
perror("utime");
return -1;
}
if (stat(files[i], &stat_buf) != 0) {
perror("stat");
return -1;
}
if (S_ISDIR(stat_buf.st_mode)) {
memset(header_buf, 0, T_BLOCKSIZE);
header->typeflag = DIRTYPE;
snprintf(header->name, T_NAMESIZE, "%s/", files[i]);
bytes_written = write(1, header_buf, T_BLOCKSIZE);
if (bytes_written != T_BLOCKSIZE) {
perror("write");
return -1;
}
}
}
memset(header_buf, 0, T_BLOCKSIZE);
bytes_written = write(1, header_buf, T_BLOCKSIZE);
if (bytes_written != T_BLOCKSIZE) {
perror("write");
return -1;
}
return 0;
}
int main(int argc, char *argv[]) {
char *files[] = {"file1.txt", "file2.txt", "directory"};
if (create_tar("archive.tar", files, 3) != 0) {
fprintf(stderr, "Failed to create archive\n");
return 1;
}
return 0;
}
```
该代码会将给定的文件和目录打包成一个名为`archive.tar`的tar文件,并输出到标准输出。其中,`create_tar`函数接受一个文件名、一个文件名列表和文件数作为参数,返回0表示成功,-1表示失败。在函数中,首先使用`stat`函数获取每个文件的元数据信息,然后填充tar头部,写入tar文件。如果文件是一个目录,需要单独处理,并将目录名后面加上斜线。最后,需要在tar文件结尾写入一个空的tar块,以表示tar文件结束。