【问题标题】:How to copy the directory from one place to another using C language?如何使用 C 语言将目录从一个地方复制到另一个地方?
【发布时间】:2021-04-06 06:29:05
【问题描述】:

我在网上搜索过,但没有找到解决办法。我想使用 C 语言将目录/文件夹从一个地方复制到另一个地方。虽然可以在命令行中使用cp,但我想用 C 语言实现。

【问题讨论】:

  • 如果你可以使用system函数,它就像命令一样简单
  • 那么有两个加一的问题需要解决: 1.1 如何复制文件? 1.2 如何遍历目录树? 2.如何对1.2中找到的每个条目(如果不是目录)使用1.1的解决方案?
  • @IrAM:这不是 OP 想要的:“* ... 可以使用 cp ... 但我想用 C 语言实现它。*”
  • 要复制一个文件,打开源文件,创建目标文件,进入一个循环,从源读取一个字节并将其写入目标,直到源指示文件结束,然后最后关闭这两个文件。

标签: c linux directory copy


【解决方案1】:

要复制文件夹,包括其中的所有文件和子文件夹,您需要遍历文件夹的内容,并为每个“条目”检查它是文件还是文件夹

  • 如果条目是文件,则可以将其作为二进制文件打开,并将所有内容写入输出路径中的新文件。
  • 如果条目是文件夹,则需要在输出路径中创建目录。

要遍历文件夹的内容,您可以使用dirent.h 中的readdir,检查条目是否是文件夹或文件lstatsys/stat.h 中的S_ISDIR,并创建文件夹@987654326 @来自sys/stat.h

【讨论】:

    【解决方案2】:

    这需要一些修饰(它应该处理目标目录的完整路径,应该考虑边缘情况等),但这是一个合理的开始:

    /* Recursively duplicate a directory tree */                                       
    #include <dirent.h>                                                                
    #include <err.h>                                                                   
    #include <errno.h>                                                                 
    #include <limits.h>                                                                
    #include <stdio.h>                                                                 
    #include <stdlib.h>                                                                
    #include <string.h>                                                                
    #include <sys/stat.h>                                                              
    #include <unistd.h>                                                                
                                                                                       
    static DIR * xopendir(const char *);                                               
    static void xclosedir(DIR *, const char *);                                        
    static void xstat(const char *, struct stat *);                                    
    static void xrealpath(const char *s, char *resolved);                              
    static void pathcat(char *p, char *n);                                             
                                                                                       
    struct dir { DIR *d; char *path, *end; };                                          
                                                                                       
    static void                                                                        
    build_dir(char *spath, char *dpath, char *name, mode_t mod)                        
    {                                                                                  
            struct dirent *f;                                                          
            struct dir src;                                                            
            struct dir dst;                                                            
                                                                                       
            src.end = strchr(spath, '\0');                                             
            dst.end = strchr(dpath, '\0');                                             
                                                                                       
            pathcat(dpath, name);                                                      
            if( mkdir(dpath, mod) == -1 && errno != EEXIST ){                          
                    err(EXIT_FAILURE, "%s", name);                                     
            }                                                                          
                                                                                       
            if( getenv("V") ){                                                         
                    printf("%s -> %s\n", spath, dpath);                                
            }                                                                          
            src.d = xopendir(src.path = spath);                                        
                                                                                       
            while( (f = readdir(src.d)) != NULL ) {                                    
                    if( !strcmp(f->d_name, ".") || !strcmp(f->d_name, "..") ){         
                            continue;                                                  
                    }                                                                  
                    if( f->d_type == DT_DIR ){                                         
                            struct stat b;                                             
                            pathcat(spath, f->d_name);                                 
                            xstat(spath, &b);                                          
                            build_dir(spath, dpath, f->d_name, b.st_mode);             
                            *src.end = '\0';                                           
                    }                                                                  
            }                                                                          
            *src.end = '\0';                                                           
            *dst.end = '\0';                                                           
            xclosedir(src.d, spath);                                                   
    } 
    int                                                                                
    main(int argc, char **argv)                                                        
    {                                                                                  
            if( argc < 2 ){                                                            
                    errx(EXIT_FAILURE, "src directory missing");                       
            }                                                                          
            if( argc < 3 ){                                                            
                    errx(EXIT_FAILURE, "target directory missing");                    
            }                                                                          
            char spath[PATH_MAX];                                                      
            char dpath[PATH_MAX];                                                      
            xrealpath(argv[1], spath);                                                 
                                                                                       
            for( argv += 2; *argv; argv++ ){                                           
                    char *name = *argv;                                                
                    if( *name == '/' ){                                                
                            dpath[0] = '\0';                                           
                    } else {                                                           
                            getcwd(dpath, sizeof dpath);                               
                    }                                                                  
                    build_dir(spath, dpath, name, 0777);                               
            }                                                                          
            return 0;                                                                  
    }                                                                                  
                                                                                       
    static void                                                                        
    xrealpath(const char *s, char *resolved)                                           
    {                                                                                  
            if( realpath(s, resolved) == NULL ){                                       
                    err(EXIT_FAILURE, "%s", s);                                        
            }                                                                          
    }                                                                                  
                                                                                       
    static DIR *                                                                       
    xopendir(const char *path)                                                         
    {                                                                                  
            DIR *d = opendir(path);                                                    
            if( d == NULL ) {                                                          
                    err(EXIT_FAILURE, "%s", path);                                     
            }                                                                          
            return d;                                                                  
    }                                                                                  
                                                                                       
    static void                                                                        
    xstat(const char *path, struct stat *buf)                                          
    {                                                                                  
            if( stat(path, buf) ){                                                     
                    err(EXIT_FAILURE, "stat %s", path);                                
            }                                                                          
    } 
    static void                                                                        
    xclosedir(DIR *d, const char *path)                                                
    {                                                                                  
            if( closedir(d) ) {                                                        
                    err(EXIT_FAILURE, "%s", path);                                     
            }                                                                          
    }                                                                                  
                                                                                       
    static void                                                                        
    pathcat(char *p, char *n)                                                          
    {                                                                                  
            if( snprintf(p, PATH_MAX, "%s/%s", p, n) > PATH_MAX - 1 ){                 
                    errx(1, "path too long");                                          
            }                                                                          
    }  
    
                                                                                
    

    【讨论】:

      猜你喜欢
      • 2014-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多