Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c语言中的复制实用程序(如*NIX中的cp),无法复制mp4或mp3文件_C_Linux_Unix - Fatal编程技术网

c语言中的复制实用程序(如*NIX中的cp),无法复制mp4或mp3文件

c语言中的复制实用程序(如*NIX中的cp),无法复制mp4或mp3文件,c,linux,unix,C,Linux,Unix,我试图通过使用管道在C中创建一个复制实用程序,就像*NIX中的cp一样 该代码适用于txt文件,但当我复制mp4或mp3文件时,它们会损坏。 对于mp4文件,我得到未选择视频或音频,对于mp3文件,我得到无法识别文件格式 我正在分配250字节的缓冲区,并分别向管道和从管道向文件(源文件和目标文件)读写250字节。文件的路径假定通过命令行参数给定 如果我读写要复制的文件的完整大小,从管道到管道,代码工作正常。但当我使用250字节的缓冲区时,它不起作用 我无法将文件大小分配给buff和childbu

我试图通过使用管道在C中创建一个复制实用程序,就像*NIX中的
cp
一样

该代码适用于txt文件,但当我复制mp4或mp3文件时,它们会损坏。 对于mp4文件,我得到
未选择视频或音频
,对于mp3文件,我得到
无法识别文件格式

我正在分配250字节的缓冲区,并分别向管道和从管道向文件(源文件和目标文件)读写250字节。文件的路径假定通过命令行参数给定

如果我读写要复制的文件的完整大小,从管道到管道,代码工作正常。但当我使用250字节的缓冲区时,它不起作用

我无法将文件大小分配给
buff
childbuff
,因为这样我将无法复制大小大于RAM(即8GB)的文件

谢谢你的帮助

 #include <stdio.h> 
 #include <unistd.h> 
 #include <stdlib.h> 
 #include <sys/types.h> 
 #include <fcntl.h> 
 #include <string.h> 
 #include <sys/stat.h>

 int main(int argc, char **argv) {
    int fildes[2];
    char ch;
    int bytes, target, handle;
    pid_t cpid;
    int sz = 0;
    struct stat st;
    stat(argv[1], & st);
    sz = st.st_size;

    char * buff = malloc(250);
    char * childbuff = malloc(250);
    pipe(fildes);
    if (argc != 3) {
      printf("Command needs two arguments");
      exit(1);
    }

    if (access(argv[1], F_OK) == -1) {
      printf("File %s , not found", argv[1]);
      exit(0);
    }
    if (access(argv[2], F_OK) != -1) {
      printf("File already exists, Do you want to overwrite ? [y,n]");
      scanf("%c", & ch);
      if (ch == 'n') {
        exit(0);
      }
      FILE * fil = fopen(argv[2], "wb");
      fclose(fil);
    }

    int tmp = 250, tmp1 = 250, wr = 0, rr = 0;

    cpid = fork();

    if (cpid == -1) {
      perror("fork");
      exit(1);
    }

    if (cpid == 0) {
      FILE * ptr = fopen(argv[2], "wb");
      while (rr < sz) {
        if (sz - rr < 250)
          tmp1 = sz - rr;
        else
          tmp1 = 250;

        rr = rr + tmp1;

        close(fildes[1]);
        read(fildes[0], childbuff, tmp1);
        close(fildes[0]);

        fwrite(childbuff, 1, tmp1, ptr);

      }
      fclose(ptr);

    } else {
      FILE * ptr = fopen(argv[1], "rb");
      while (wr < sz) {
        if (sz - wr < 250)
          tmp = sz - wr;
        else
          tmp = 250;

        wr = wr + tmp;

        close(fildes[0]);
        bytes = fread(buff, 1, tmp, ptr);
        write(fildes[1], buff, bytes);
      }
      fclose(ptr);

    }
  }
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符**argv){
int fildes[2];
char ch;
int字节,目标,句柄;
pid_t cpid;
int sz=0;
结构统计;
统计(argv[1],&st);
sz=标准尺寸;
char*buff=malloc(250);
char*childbuff=malloc(250);
管道(菲尔德斯);
如果(argc!=3){
printf(“命令需要两个参数”);
出口(1);
}
if(访问(argv[1],F_OK)=-1){
printf(“文件%s,未找到”,argv[1]);
出口(0);
}
如果(访问(argv[2],F_确定)!=-1){
printf(“文件已存在,是否覆盖?[y,n]”);
scanf(“%c”和“ch”);
如果(ch='n'){
出口(0);
}
文件*fil=fopen(argv[2],“wb”);
fclose(fil);
}
int tmp=250,tmp1=250,wr=0,rr=0;
cpid=fork();
如果(cpid==-1){
佩罗尔(“福克”);
出口(1);
}
如果(cpid==0){
文件*ptr=fopen(argv[2],“wb”);
而(rr
两个明显的问题

  • 您不检查
    read
    write
    调用的返回值,因此您不知道实际读取或写入了多少数据(可能比请求的数据少)

  • 第一次通过循环关闭读取文件描述符,因此在第二次和后续迭代中,它将被关闭,读取将失败。您没有注意到,因为您没有检查read的返回值


道德-始终检查您呼叫的返回值。

请使用类似“下次”的方式格式化您的代码,否则很难读取这行代码,看起来可疑
读取(fildes[0],childbuff,tmp1);关闭(菲尔德斯[0])为什么在从管道中读取一个缓冲区后立即关闭管道?这样做比管道、分叉和混合fread/fwrite与read/write所需要的复杂得多。这个bug可能就在那些乱七八糟的地方,但即使它工作正常,也比从文件a读然后写到文件B的简单循环要慢。如果代码工作正常与否与文件格式无关。每当文件大于您读取的一部分(250字节)时,由于
close()
请不要使用,父进程将不会读取数据。它破坏
#include
指令。OP:问题中的代码应该与您实际编译的代码匹配。如果重新格式化,请在将其复制到问题中之前编译重新格式化的版本。(我刚刚更正了
#include
指令。)