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

标签 c linux unix

我正在尝试用 C 语言制作一个复制实用程序,就像 cp在 *NIX 中,通过使用管道。

该代码对于 txt 文件工作正常,但当我复制 mp4 或 mp3 文件时,它们会损坏。 对于 mp4 文件,我得到 No video or audio selected对于 mp3,我得到 Failed to recognize file format

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

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

我无法将文件大小分配给buffchildbuff因为那样我将无法复制大小大于我的 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);

    }
  }

最佳答案

两个明显的问题

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

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

道德 - 始终检查调用的返回值。

关于c 中的复制实用程序(如 *NIX 中的 cp),无法复制 mp4 或 mp3 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48870854/

相关文章:

linux - 在没有 root 权限的情况下安装 GNU parallel

python - 从 C 执行 python 脚本

c++ - 如何查看库的内部(尤其是 C 标准库)?

c - 从未初始化的变量创建指针是否有副作用?

linux - 如何在 BSD 进程记帐文件中获取脚本名称?

json - JQ 使用 bash 创建 json 数组

linux - 如何跳过文件夹中特定模式的文件

linux - 如何根据日期和时间删除目录

c - || 的优先级C 中的 and && 运算符

linux - 如何查找或计算 Linux 进程的页表大小和其他内核核算?