C语言编程中的归档文件提取

C语言编程中的归档文件提取,c,extract,archive,C,Extract,Archive,我想在这里进一步阐述这个问题: 在这里,它讨论了获取已存档的文件并将其解压缩并返回到文件表单,而不使用命令ar-x 答案中的算法说明了以下步骤: 获取要提取的文件名,也可以从命令行中提取 为结构创建内存以读取每个文件的元数据 从存档文件中读取所有元数据 有人能给我一些在这些步骤中使用的函数的提示吗?我真的不知道它在第2步讨论的是什么结构。给出的是归档和提取细节+代码的实现。要归档文件,请使用此最简单的归档文件格式。 标题|内容 标头包含有关文件的元数据,包括标头的大小(不包括标头大小数据)、文

我想在这里进一步阐述这个问题:

在这里,它讨论了获取已存档的文件并将其解压缩并返回到文件表单,而不使用命令
ar-x

答案中的算法说明了以下步骤:

  • 获取要提取的文件名,也可以从命令行中提取
  • 为结构创建内存以读取每个文件的元数据
  • 从存档文件中读取所有元数据
  • 有人能给我一些在这些步骤中使用的函数的提示吗?我真的不知道它在第2步讨论的是什么结构。

    给出的是归档和提取细节+代码的实现。要归档文件,请使用此最简单的归档文件格式。 标题|内容 标头包含有关文件的元数据,包括标头的大小(不包括标头大小数据)、文件名和相应的文件大小,以/分隔。我使用/作为分隔符,因为它们不会出现在Linux简单文件名中,除非它是路径名。如果计划包含路径名,可以使用另一个分隔符

    正文包含一个接一个附加的每个文件的内容

    以下是我存档文件的格式


    文件大小/FILE1名称/FILE1大小/FILE2名称/FILE2大小/BODY 我使用下面的C结构收集单个文件的元数据,用于归档和提取

    struct mdata
    {
       char name[255];
       FILE *fp;
       int size;
       int nsize;
       int ssize;
       struct mdata *next;
    };
    
    我使用链表来包含文件元数据列表

    存档代码:./archive file1 file2 archive1

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define BSIZE 2048
    
    
    struct mdata
    {
        char name[255];
        FILE *fp;
        int size;
        int nsize;
        int ssize;
        struct mdata *next;
    };
    
    struct mdata *mhead = NULL, *current = NULL;
    
    int getsize(FILE *fp)
    {
        int size = 0;
        fseek(fp, 0L, SEEK_END);      
        size  = ftell(fp);
        fseek(fp, 0L, SEEK_SET);   
        return size;
    }
    
    int add(char *name)
    {    
        FILE *fp;
        char ntemp[255];
        struct mdata *newm;
        newm = (struct mdata *)malloc(sizeof(struct mdata));
        strcpy(newm->name, name);    
        fp = fopen(name, "r+");  
        newm->fp = fp;
        newm->size = getsize(fp);  
        newm->nsize = strlen(name);
        sprintf(ntemp, "%d", newm->size);
        newm->ssize = strlen(ntemp);
        newm->next = NULL;
        printf("File %s is being processed...\n", name);
        if(mhead == NULL) 
        {
            mhead = newm;
            current = newm;
        }
        else
        {
            current->next = newm;
            current = newm;
        }
    }
    
    int preproc(int argc, char** argv)
    {
        int i;
    
        for(i = 1; i <= argc-2; i++)  
        {   
            add(argv[i]);  
        }    
    }
    
    int main(int argc, char** argv) 
    {
        char block[BSIZE];
        char stsize[5];
        char shsize[100];
        int rsize = 0;
        int tnsize = 0, tssize = 0, hsize = 0, scount = 0;
        struct mdata *ptr;
        FILE *fpar, *fp;
    
        //CREATE HEADER
        printf("Pre-processing the files to collect meta data...\n");
        preproc(argc, argv);
        printf("Pre-processing completed.\n");
        printf("Compiling header information.\n");
        fpar = fopen(argv[argc-1], "w+");
        ptr = mhead;
        while(ptr != NULL)
        {
            tnsize += ptr->nsize;        
            tssize += ptr->ssize;
            ptr = ptr->next;
            scount +=2;
        }
        hsize = tnsize+tssize+scount+1; 
        printf("Total length of file names is %d\n", tnsize);
        printf("Total length of file sizes is %d\n", tssize);
        printf("Total size of header except file size is %d.\n", hsize);
        sprintf(shsize, "%d/", hsize); //10 bytes of header size
        fwrite(shsize, 1, strlen(shsize), fpar);
        ptr = mhead;
        while(ptr != NULL)
        {
            fwrite(ptr->name, 1, ptr->nsize, fpar);   
            fwrite("/", 1, 1, fpar);
            sprintf(stsize, "%d", ptr->size);
            fwrite(stsize, 1, ptr->ssize, fpar);  
            fwrite("/", 1, 1, fpar);
            ptr = ptr->next;
        }    
        printf("The header created and written to archieve file.\n");
        //CREATE BODY
        ptr = mhead;
        while(ptr != NULL)
        {
            fp = ptr->fp;
            while(rsize = fread(block, 1, sizeof(block), fp))
            {
                fwrite(block, 1, rsize, fpar);
            }
            ptr = ptr->next;
        }   
        printf("Contents of all files written to archieve file.\n");
        fclose(fpar);  
        return 0;
    }
    
    #包括
    #包括
    #包括
    #定义BSIZE2048
    结构mdata
    {
    字符名[255];
    文件*fp;
    整数大小;
    内化;
    int ssize;
    结构mdata*next;
    };
    struct mdata*mhead=NULL,*current=NULL;
    int getsize(文件*fp)
    {
    int size=0;
    fseek(fp,0L,SEEK_END);
    尺寸=ftell(fp);
    fseek(fp、0L、SEEK\u集);
    返回大小;
    }
    int add(字符*名称)
    {    
    文件*fp;
    字符ntemp[255];
    结构mdata*newm;
    newm=(struct mdata*)malloc(sizeof(struct mdata));
    strcpy(newm->name,name);
    fp=fopen(名称“r+”);
    newm->fp=fp;
    newm->size=getsize(fp);
    newm->nsize=strlen(名称);
    sprintf(ntemp,“%d”,newm->size);
    newm->ssize=strlen(ntemp);
    newm->next=NULL;
    printf(“文件%s正在处理…\n”,名称);
    if(mhead==NULL)
    {
    mhead=newm;
    电流=newm;
    }
    其他的
    {
    当前->下一步=newm;
    电流=newm;
    }
    }
    打印预处理(打印argc,字符**argv)
    {
    int i;
    对于(i=1;i nsize;
    tssize+=ptr->ssize;
    ptr=ptr->next;
    Scont+=2;
    }
    hsize=tnsize+tssize+scont+1;
    printf(“文件名的总长度为%d\n”,tnsize);
    printf(“文件大小的总长度为%d\n”,tssize);
    printf(“除文件大小外,头的总大小为%d.\n”,hsize);
    sprintf(shsize,“%d/”,hsize);//头大小的10字节
    fwrite(shsize,1,strlen(shsize),fpar);
    ptr=mhead;
    while(ptr!=NULL)
    {
    fwrite(ptr->name,1,ptr->nsize,fpar);
    fwrite(“/”,1,1,fpar);
    sprintf(stsize,“%d”,ptr->size);
    写入(stsize,1,ptr->ssize,fpar);
    fwrite(“/”,1,1,fpar);
    ptr=ptr->next;
    }    
    printf(“创建并写入archive文件的头文件。\n”);
    //创造身体
    ptr=mhead;
    while(ptr!=NULL)
    {
    fp=ptr->fp;
    而(rsize=fread(block,1,sizeof(block,fp))
    {
    fwrite(区块1,rsize,fpar);
    }
    ptr=ptr->next;
    }   
    printf(“写入存档文件的所有文件的内容。\n”);
    fclose(fpar);
    返回0;
    }
    
    提取代码:./extract archive

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define BSIZE 2048
    
    
    struct mdata
    {
        char name[255];
        FILE *fp;
        int size;
        int nsize;
        int ssize;
        struct mdata *next;
    };
    
    struct mdata *mhead = NULL, *current = NULL;
    
    int min(int x, int y)
    {
        if(x < y) return x;
        else return y;
    }
    int getsize(FILE *fp)
    {
        int size = 0;
        fseek(fp, 0L, SEEK_END);      
        size  = ftell(fp);
        fseek(fp, 0L, SEEK_SET);   
        return size;
    }
    
    int add(char *name, int size)
    {    
        char ntemp[255];
        struct mdata *newm;
        newm = (struct mdata *)malloc(sizeof(struct mdata));
        strcpy(newm->name, name);    
        newm->size = size;
        newm->nsize = strlen(name);
        sprintf(ntemp, "%d", newm->size);
        newm->ssize = strlen(ntemp);
        newm->next = NULL;
        printf("File %s is being processed...\n", name);
        if(mhead == NULL) 
        {
            mhead = newm;
            current = newm;
        }
        else
        {
            current->next = newm;
            current = newm;
        }
    }
    
    int readh(FILE *fp1)
    {
        int i = 0, j= 1 ;    
        int hsize = 0, size = 0;
        int byte;
        char shsize[50]; 
        char name[255];
        char ssize[50];
        while((byte = fgetc(fp1))!='/')
        {
            shsize[i] = (char)byte;
            i++;
        }
        shsize[i] = '\0';
        hsize = atoi(shsize);
        hsize += strlen(shsize);
        printf("The total size of header is %d.\n", hsize);
        printf("Contents starts at %dth byte.\n", hsize);
        //COLLECT NAMES AND SIZES
        j = strlen(shsize)+1;
        while(j <= hsize-1)
        {
            i = 0;
            while((byte = fgetc(fp1))!='/')
            {
                name[i++] = byte;
                j++;
            }
            j++;
            name[i] = '\0';
            i = 0;
            while((byte = fgetc(fp1))!='/')
            {
                ssize[i++] = byte;
                j++;
            }     
            j++;
            ssize[i] = '\0';
            size = atoi(ssize);
            printf("File '%s' with size %d added to list.\n", name, size);
            add(name, size);
            printf("File '%s' processing completed.\n", name);
        }
        printf("File meta data collection successfully completed.\n");
    }
    
    int main(int argc, char** argv) 
    {
        char block[BSIZE];
        char stsize[5];
        char shsize[100];
        int rsize = 0;
        int tnsize = 0, tssize = 0, hsize = 0, scount = 0;
        int totsize = 0;
        int unreadcount = 0;
        struct mdata *ptr;
        FILE *fpar, *fp;
    
        //COLLECTING HEADER
        printf("Opening file %s...\n", argv[1]);
        fpar = fopen(argv[1], "r+");
        if(fpar == NULL)
        {
            printf("Error opening file %s.\n", argv[1]);
        }
        readh(fpar);
        ptr = mhead;
        lseek(fpar, hsize+1, SEEK_SET);
        while(ptr != NULL)
        {
            totsize = 0;
            printf("Creating file %s...\n", ptr->name);
            fp = fopen(ptr->name, "w+"); 
            printf("Writing %d bytes of %s...\n", ptr->size, ptr->name);
            unreadcount = ptr->size;
            while(unreadcount > 0)
            {
                if(sizeof(block)>= unreadcount)
                {
                    rsize = fread(block, 1, unreadcount, fpar);
                }
                else
                {
                    rsize = fread(block, 1, sizeof(block), fpar);
                }
                unreadcount -= rsize;
                totsize += rsize;
                fwrite(block, 1, rsize, fp);
            }
            printf("Written %d bytes to file %s.\n", totsize, ptr->name);
            ptr = ptr->next;
        }
        printf("Extraction completed.\n");
        fclose(fpar);  
        return 0;
    }
    
    #包括
    #包括
    #包括
    #定义BSIZE2048
    结构mdata
    {
    字符名[255];
    文件*fp;
    整数大小;
    内化;
    int ssize;
    结构mdata*next;
    };
    struct mdata*mhead=NULL,*current=NULL;
    最小整数(整数x,整数y)
    {
    如果(xname,name);
    newm->size=size;
    newm->nsize=strlen(名称);
    sprintf(ntemp,“%d”,newm->size);
    newm->ssize=strlen(ntemp);
    newm->next=NULL;
    printf(“文件%s正在处理…\n”,名称);
    if(mhead==NULL)
    {
    mhead=newm;
    电流=newm;
    }
    其他的
    {
    当前->下一步=newm;
    电流=newm;
    }
    }
    int readh(文件*fp1)
    {
    int i=0,j=1;
    int-hsize=0,size=0;
    整数字节;
    字符大小[50];
    字符名[255];
    char-ssize[50];
    而((字节=fgetc(fp1))!='/'))
    {
    shsize[i]=(字符)字节;
    i++;
    }
    shsize[i]='\0';
    hsize=atoi(shsize);
    hsize+=strlen(shsize);
    printf(“标题的总大小为%d.\n”,hsize);
    printf(“内容从%dth字节开始。\n”,hsize);
    //收集姓名和尺码
    j=strlen(shsize)+1;
    (j)姓名;
    fp=fopen(ptr->name,“w+”);
    printf(“写入%s..n的%d字节”,ptr->size,ptr->name);
    unreadcount=ptr->size;
    而(未计数>0)
    {
    if(sizeof(block)>=unreadcount)
    {
    rsize=fread(块,1,未计算,fpar);
    }
    其他的
    {
    rsize=fread(块,1,块的尺寸,fpar);
    }
    未计算-=rsize;
    totsize+=rsize;
    fwrite(区块1,rsize,fp);
    }
    printf(“已将%d个字节写入文件%s。\n”,totsize,ptr->name);
    ptr=ptr->next;
    }
    printf(“提取完成。\n”);
    fclose(fpar);
    返回0;
    }
    
    您的问题是a吗