Linux--简单copy程序
2017-02-24 15:57
302 查看
1. 测试main函数
2. copy.h 头文件,定义了几个函数
3. copy.c文件,小程序支持拷贝文件和目录,只不过拷贝目录是将目录里面的文件拷贝到另外一个目录中,支持嵌套
可能还不太完善,不能和Linux 的CP比较,纯属娱乐
#include <stdio.h> #include <string.h> #include "copy.h" int main(int argc, char *argv[]) { if (argc != 3) { printf("usage: %s src dst\n", argv[0]); return -1; } char src[MAX_PATH] = {0}; char dst[MAX_PATH] = {0}; strncpy(src, argv[1], strlen(argv[1])); strncpy(dst, argv[2], strlen(argv[2])); int copyResult = copy(src, dst); if (copyResult == ERROR_SUCCESS_OK) { printf("copy complete...\n"); } else { printf("error in copying\n"); specify_error(copyResult, src); } return 0; }
2. copy.h 头文件,定义了几个函数
#ifndef _COPY_H_ #define _COPY_H_ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <dirent.h> #include <string.h> #define MAX_PATH 255 //error detail info enum error_info { ERROR_SUCCESS_OK = 0, ERROR_FILE_NO_EXISTS = -1, ERROR_FILE_STAT_ERROR = -2, ERROR_FILE_UNKNOWN_ERROR = -3, ERROR_FILE_CREATE_ERROR = -4, ERROR_FILE_OPEN_ERROR = -5, ERROR_FILE_COPY_WRITE = -6, ERROR_FILE_COPY_READ = -7, ERROR_COPY_PATTERN_ERROR = -8, ERROR_COPY_MKDIR_ERROR = -9 }; enum file_type { FILE_DIR = 1, FILE_REGULAR = 2, FILE_SOCKET = 3, FILE_LINK = 4, FILE_FIFO = 5, FILE_BLOCK = 6, FILE_CHAR = 7, FILE_UNKNOWN = 8, FILE_NEED_CREATE = 9, FILE_NOT_EXISTS = 10, FILE_DIR_NOT_EXISTS = 11 }; enum dir_type { DIR_ABSOLUTE = 1, DIR_RELATIVE = 2 }; int copy(const char *src, const char *dst); int check_file(const char *file); int check_file_type(const char *file); long int get_file_length(const char *file); int analysis_file(const char *file); int is_absolute_dir(const char *dir); void specify_error(int errno, const char *file); int file_create(const char *file, int flags, mode_t mode); int core_copy(int srcFileType, const char *src, int dstFileType, const char *dst); void get_file_name(const char *file, char *fileName); int core_read_write(const char *src, const char *dst); int do_dir(const char *src, const char *dst); #endif //_COPY_H_
3. copy.c文件,小程序支持拷贝文件和目录,只不过拷贝目录是将目录里面的文件拷贝到另外一个目录中,支持嵌套
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <assert.h> #include <dirent.h> #include "copy.h" int copy(const char *src, const char *dst) { assert(src != NULL); assert(dst != NULL); int srcFileType; if ((srcFileType = check_file_type(src)) == ERROR_FILE_NO_EXISTS) { return ERROR_FILE_NO_EXISTS; } else if (srcFileType == FILE_UNKNOWN) { return ERROR_FILE_UNKNOWN_ERROR; } int dstFileType = analysis_file(dst); if (dstFileType == FILE_NOT_EXISTS || dstFileType == FILE_DIR_NOT_EXISTS) { return ERROR_FILE_NO_EXISTS; } if (dstFileType == FILE_NEED_CREATE) { if (file_create(dst, 0, 0) < 0) { return ERROR_FILE_CREATE_ERROR; } dstFileType = FILE_REGULAR; } return core_copy(srcFileType, src, dstFileType, dst); } int check_file(const char *file) { assert(file != NULL); if (access(file, F_OK) < 0) { return FILE_NOT_EXISTS; } return ERROR_SUCCESS_OK; } int check_file_type(const char *file) { assert(file != NULL); if (check_file(file) < 0) { return ERROR_FILE_NO_EXISTS; } struct stat fileInfo; if (stat(file, &fileInfo) < 0) { return ERROR_FILE_STAT_ERROR; } if (fileInfo.st_mode & S_IFDIR) { return FILE_DIR; } else if (fileInfo.st_mode & S_IFREG) { return FILE_REGULAR; } else if (fileInfo.st_mode & S_IFSOCK) { return FILE_SOCKET; } else if (fileInfo.st_mode & S_IFLNK) { return FILE_LINK; } else if (fileInfo.st_mode & S_IFIFO) { return FILE_FIFO; } else if (fileInfo.st_mode & S_IFBLK) { return FILE_BLOCK; } else if (fileInfo.st_mode & S_IFCHR) { return FILE_CHAR; } else { return FILE_UNKNOWN; } } long int get_file_length(const char *file) { assert(file != NULL); if (check_file(file) < 0) { return ERROR_FILE_NO_EXISTS; } struct stat fileInfo; if (stat(file, &fileInfo) < 0) { return ERROR_FILE_STAT_ERROR; } return (long int)fileInfo.st_size; } int analysis_file(const char *file) { //1 check file exists int fileExists = check_file(file); if (fileExists == ERROR_SUCCESS_OK) { int fileType = check_file_type(file); return fileType; } //2 file is not exists //2.1 check basedir char file_path[MAX_PATH] = {0}; strncpy(file_path, file, strlen(file)); char *dirPos = strrchr(file_path, '/'); if (dirPos == NULL) { //current dir return FILE_NEED_CREATE; } if (dirPos != file_path + strlen(file_path)) //type '/' { //create a file then return dirPos = '\0'; fileExists = check_file(file_path); if (fileExists == FILE_NOT_EXISTS) { return FILE_NOT_EXISTS; } else { return FILE_NEED_CREATE; } } else { return FILE_DIR_NOT_EXISTS; } } int is_absolute_dir(const char *dir) { assert(dir != NULL); if (dir[0] == '/') { return DIR_ABSOLUTE; } else { return DIR_RELATIVE; } } void specify_error(int errno, const char *file) { switch(errno) { case ERROR_SUCCESS_OK: { fprintf(stderr, "file or directory[%s] is ok\n", file); } break; case ERROR_FILE_NO_EXISTS: { fprintf(stderr, "file or directory[%s] is not exists\n", file); } break; case ERROR_FILE_STAT_ERROR: { fprintf(stderr, "file or directory[%s] stat error, maybe not permits\n", file); } break; case ERROR_FILE_UNKNOWN_ERROR: { fprintf(stderr, "file or directory[%s] is unknown type\n", file); } break; case ERROR_FILE_CREATE_ERROR: { fprintf(stderr, "create file or directory[%s] error, maybe not permits\n", file); } break; case ERROR_COPY_PATTERN_ERROR: { fprintf(stderr, "copy[%s] error, cannot copy a directory to a file\n", file); } break; case ERROR_COPY_MKDIR_ERROR: { fprintf(stderr, "mkdir error\n"); } break; default: break; } } int file_create(const char *file, int flags, mode_t mode) { assert(file != NULL); if (mode == 0) { mode = 0644; } if (flags == 0) { flags = O_CREAT | O_RDWR; } int fd = open(file, flags, mode); if (!fd) { return ERROR_FILE_CREATE_ERROR; } close(fd); return ERROR_SUCCESS_OK; } int core_copy(int srcFileType, const char *src, int dstFileType, const char *dst) { assert(src != NULL); assert(dst != NULL); if (srcFileType != FILE_DIR) { if (dstFileType != FILE_DIR) //file to file { return core_read_write(src, dst); } else //file to dir { char fileName[MAX_PATH] = {0}; get_file_name(src, fileName); char dirFileName[MAX_PATH] = {0}; strncpy(dirFileName, dst, strlen(dst)); strncat(dirFileName, "/", strlen("/")); strncat(dirFileName, fileName, strlen(fileName)); if (file_create(dirFileName, 0, 0) < 0) { return ERROR_FILE_CREATE_ERROR; } return core_read_write(src, dirFileName); } } else { if (dstFileType != FILE_DIR) { unlink(dst); return ERROR_COPY_PATTERN_ERROR; } else { return do_dir(src, dst); } } } void get_file_name(const char *file, char *fileName) { assert(file != NULL); char *posBegin = strrchr(file, '/'); if (!posBegin) { strncpy(fileName, file, strlen(file)); } else { strncpy(fileName, posBegin+1, file + strlen(file) - posBegin); } } int core_read_write(const char *src, const char *dst) { int fdSrc = open(src, O_RDONLY); if (!fdSrc) { return ERROR_FILE_OPEN_ERROR; } int fdDst = open(dst, O_RDWR | O_TRUNC); if (!fdDst) { return ERROR_FILE_OPEN_ERROR; } char buffer[1024] = {0}; ssize_t readSize = 0; ssize_t writeSize = 0; while((readSize = read(fdSrc, buffer, sizeof(buffer))) > 0) { writeSize = write(fdDst, buffer, readSize); if (writeSize != readSize) { close(fdSrc); close(fdDst); unlink(dst); return ERROR_FILE_COPY_WRITE; } memset(buffer, 0, sizeof(buffer)); } if (readSize < 0) { close(fdSrc); close(fdDst); unlink(dst); return ERROR_FILE_COPY_READ; } close(fdSrc); close(fdDst); return ERROR_SUCCESS_OK; } int do_dir(const char *src, const char *dst) { DIR * root = opendir(src); struct dirent *dirInfo = NULL; while((dirInfo = readdir(root)) != NULL) { if (strcmp(dirInfo->d_name, ".") == 0 || strcmp(dirInfo->d_name, "..") == 0) { continue; } char fileSrcName[MAX_PATH] = {0}; strncpy(fileSrcName, src, strlen(src)); strncat(fileSrcName, "/", strlen("/")); strncat(fileSrcName, dirInfo->d_name, strlen(dirInfo->d_name)); if (dirInfo->d_type & DT_DIR) { char fileDstName[MAX_PATH] = {0}; strncpy(fileDstName, dst, strlen(dst)); strncat(fileDstName, "/", strlen("/")); strncat(fileDstName, dirInfo->d_name, strlen(dirInfo->d_name)); if (check_file(fileDstName) == FILE_NOT_EXISTS) { if (mkdir(fileDstName, 0755) < 0) { return ERROR_COPY_MKDIR_ERROR; } } do_dir(fileSrcName, fileDstName); } else { char fileDstName[MAX_PATH] = {0}; strncpy(fileDstName, dst, strlen(dst)); strncat(fileDstName, "/", strlen("/")); strncat(fileDstName, dirInfo->d_name, strlen(dirInfo->d_name)); if (file_create(fileDstName, 0, 0) < 0) { return ERROR_FILE_CREATE_ERROR; } core_read_write(fileSrcName, fileDstName); } } closedir(root); return ERROR_SUCCESS_OK; }
可能还不太完善,不能和Linux 的CP比较,纯属娱乐
相关文章推荐
- redhat 开机启动程序 Linux中的简单备份
- linux下的简单的shell程序
- Linux下的一个简单汇编程序, .long声明数据的长度问题!
- 简单的Linux关机程序
- linux两个程序通过共享内存通信的一个简单例子
- Linux下,使用C/C++编写一个简单的消息处理程序
- 一个简单的linux下网络程序实例-网络编程入门 收藏
- linux下编译C程序——gdb简单调试
- linux下简单的tomcat服务监测程序
- 一段简单程序为什么在linux终端与win控制台下运行效果不同?(望高手指点)
- 简单的Linux客户-服务器网络程序
- Linux下最简单的汇编程序
- 简单的跨linux和windows的程序通用框架
- linux下socket实现TCP通信的简单程序接口封装
- 如何在linux下创建一个简单的JNI程序HelloWorld
- Linux平台下编译运行wxWidgets简单窗口程序
- Linux网络编程-简单的客户端和服务器通讯程序开发入门(2)
- 在Linux下编写C++程序 简单的小程序
- 在windows电脑上运行linux程序软件的简单方法
- Linux上简单的meego开发QT程序