我只是尝试在 unix 中编写类似 tar 命令的 c 代码。我的问题是提取存档文件。您将看到文件注释“这里有问题”的结尾。我正在尝试提取存档文件。这是二进制文件。第一个字节是给我们文件的数量。第二个字节是第一个文件的名称长度。例如“file.c”的长度是 6。第三个字节是第一个文件的名称字符串。所以“file.c”。并开始第二个文件的信息......去最后一个文件的信息。所以最后开始每个文件都包含之后和之后。
存档文件 = N-I1-I2....-Ik-B1-B2....-Bk I = LSZ
N 是文件数。1 字节 I 是有关文件的信息。B 是文件包含。
L 是文件名的长度。1 字节 S 是文件名字符串 Z 是文件大小
所以,我可以从二进制文件中读取 N、L、S,但不能读取 Z!我找不到它。
#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);
}
}