简体   繁体   中英

How to copy the directory from one place to another using C language?

I have searched online but didn't a solution. I want to copy the directories/folders from one place to another using C language. Although it could be possible using cp in command line but I want to implement that in C language.

To copy a folder, including all files and subfolders inside, you need to iterate over the content of the folder, and for each "entry" check if it's a file or folder

  • if the entry is a file then you can open it as binary and write all the content to a new file in the output path.
  • if the entry is a folder then you need to create the directory in the output path.

To iterate over the content of the folder you can use readdir from dirent.h , to check if an entry is a folder or file lstat and S_ISDIR from sys/stat.h , and to create folder mkdir from sys/stat.h .

This needs some polishing (it ought to handle a full path for a target dir, should think about edge cases, etc.), but this is a reasonable start:

/* 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");                                          
        }                                                                          
}  

                                                                            

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM