首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >归档文件在c中提取

归档文件在c中提取
EN

Stack Overflow用户
提问于 2013-05-05 04:37:26
回答 2查看 585关注 0票数 0

我正在尝试编写c代码,就像unix中的tar命令一样。我的问题是提取归档文件。你会看到文件末尾的注释"problem here“。我正在尝试提取存档文件。这是二进制文件。第一个字节是给我们的文件数。第二个字节是第一个文件的名称长度。例如"file.c“的长度是6。第三个字节是第一个文件的名称string.so "file.c”。并开始第二个文件的informations......going最后一个文件的信息。因此,最后在前后启动每个包含文件。

归档文件= N-I1-I2....-Ik-B1-B2....-Bk i= L-S-Z

N是文件的数量。字节i是关于文件的信息。B是文件包含。

L是文件名的长度。1字节S是文件名字符串Z是文件大小

所以,我可以从二进制文件中读取N,L,S,但不能读取Z!我找不到了。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#define BUFSIZE 4096



struct stat st;

struct inputfiles{
  int numchar;
  char *filename;
  unsigned int filesize;
}file[255];

struct outputfiles{
  int num_char;
  char *file_name;
  unsigned int file_size;
}outfile[255];


int main(int argc,char *argv[])
{

  int copyfile(char *,char *);

  int i,j,k,m,h;
  int input_file,output_file;
  int fd;  
  int infile,outfile,arcfile;
  char buffer[BUFSIZE];
  char n;
  char flength;
 unsigned int file_len;
  char *f_name;

  char tempsize;
 unsigned  int sizeoffile;

  ssize_t nread,xread;




  input_file=argc-3;

  if(argc<=2)
    {
      fprintf(stderr,"Error: you must enter least 3 argument\n");
    exit(1);
    }
  else if(strcmp(argv[1],"-c")==0)
    {
      if((outfile=open(argv[2],O_WRONLY | O_CREAT,0644))==-1)
      {
      fprintf(stderr,"Error: Archive file can't open %s\n",argv[2]);
       remove(argv[2]);
      exit(1);
      }

      /*** write number of files into the archive file ***/
        write(outfile,(char*)&input_file,sizeof(char)); //UPDATED 


      j=0;    
      for(i=3;i<argc;i++)
    {
         file[j].numchar=strlen(argv[i]);


         /**** write filename size into archive file ****/ 
         write(outfile,(char*)&file[j].numchar,sizeof(char)); //UPDATED 



         file[j].filename=malloc(sizeof(file[j].numchar));
         strcpy(file[j].filename,argv[i]);

         /**** write filename into the archive file ****/
         write(outfile,file[j].filename,file[j].numchar);

         stat(argv[i],&st);
         file[j].filesize=st.st_size;     

         /**** write size of file into the archive file ****/
         write(outfile,&file[j].filesize,sizeof(int));               //UPDATED  HERE IS 4 BYTES

         j++;
    }   

      for(m=3;m<argc;m++)
    {
      if((infile=open(argv[m],O_RDONLY))==-1)
        {
          fprintf(stderr,"Error: File can't open %s\n",argv[m]);
          exit(1);
        }

      while((nread=read(infile,buffer,BUFSIZE))>0)
        {
          if(write(outfile,buffer,nread)<nread)
        {
          fprintf(stderr,"Error : input file size too much\n");
        }

          if(nread==-1)
        {
          fprintf(stderr,"Error occurred while reading.\n");
          exit(1);
        }
        }

    }
    }


/******* Extracting Archive File  *********/ 


  else if((strcmp(argv[1],"-x")==0))
    {
      if(argc!=3)
    {
      fprintf(stderr,"Error : you must enter 3 argument for extract \n");
      exit(1);
    }
      else
    {
     if((arcfile=open(argv[2],O_RDONLY))==-1)
       {
          fprintf(stderr,"Error:File can't open %s\n",argv[2]);
          remove(argv[2]);
          exit(1);
        }

     read(arcfile,&n,sizeof(char)); //read first byte of archive file
     output_file=(int)n;  // get number of output files
     printf("there is a %d files.\n",output_file);
     for(m=0;m<n;m++)   //loop for get information about each output file
       {
         read(arcfile,&flength,sizeof(char)); //read second byte
         file_len=((int)flength);   //get filename length


         f_name=malloc(file_len+1);   //malloc for filename
         read(arcfile,f_name,file_len);  //read size of filename length bytes and get filename string

         read(arcfile,&tempsize,sizeof(char)); //read size of file  <--- problem here
         sizeoffile=(int)tempsize;

     printf("file name length: %d\n",file_len);    
     printf("file name: %s\n",f_name);
     printf("file size: %d\n",sizeoffile);
       }

    }

    }
  else {
    fprintf(stderr,"invalid command line\n");
    exit(1);
  }
}
EN

回答 2

Stack Overflow用户

发布于 2013-05-05 04:50:24

当您写出文件名和文件大小时,您将它们写为ints,占用4个字节:

代码语言:javascript
复制
write(outfile,&file[j].numchar,sizeof(file[j].numchar) /* = sizeof(int) */);
...
write(outfile,&file[j].filesize,sizeof(file[j].filesize) /* = sizeof(int) */);

但是当你读回它们的时候,你会期望它们是chars,占用一个字节:

代码语言:javascript
复制
read(arcfile,&flength,sizeof(char));
...
read(arcfile,&tempsize,sizeof(char));

尝试将大小写为单个字节,或者更好的做法是,仅使用4个字节作为文件名和文件大小。(更好,因为这样你就不必担心文件和文件名太长了)

要将文件名和长度写出为单个字节,请将它们转换为chars:

代码语言:javascript
复制
char to_write = file[j].numchar;
write(outfile, &to_write, sizeof(char));
...
to_write = file[j].filesize;
write(outfile, &to_write, sizeof(char));
票数 1
EN

Stack Overflow用户

发布于 2013-05-05 11:25:41

我把it.problem定义为结构体。我必须定义unsigned char numchar,而不是int numchar!终于来了。谢谢你的帮助,我的朋友。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16378737

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档