关于拷贝文件,前面写过一个例子:点击打开链接 ,可以看看,实现cp命令。

这次我们实现一个目录和文件的拷贝,综合点。

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#include <sys/stat.h>
#include <dirent.h>

void copy_file(const char *src , const char *dest);
void copy_directory(const char *src , const char *dest , const char *name);

int main(int argc , char *argv[])
{
	//参数校验
	if(argc <  3)
	{
		perror("argument error ... ");
		return -1 ;
	}

	struct stat  state ;
	stat(argv[argc-1] , &state);
	//如果最后一个参数不是目录的话报错退出
	if(!S_ISDIR(state.st_mode))
	{
		fprintf(stderr , "the last one is not a directory ... \n");
		return -2 ;
	}

	int i ;
	char buffer[256] = {0};
	for(i = 1 ; i < argc-1 ; i++)
	{
	//	printf("argv[%d]:%s\n" , i , argv[i]);
		stat(argv[i] , &state);
		if(S_ISREG(state.st_mode))  //判断参数是否为单独的文件
		{
			sprintf(buffer , "%s/%s" , argv[argc-1] , argv[i]);
			//拷贝文件
			copy_file(argv[i] , buffer);
			continue ;
		}
		if(S_ISDIR(state.st_mode))  //判断参数是否为目录
		{
			//拷贝文件夹
			copy_directory(argv[i] , argv[argc-1] , argv[i]);
			continue ;
		}
	}

	return 0 ;
}
void copy_file(const char *src , const char *dest)
{
	int  src_fd ;
	int  dest_fd ; 

	src_fd = open(src , O_RDONLY);
	if(-1 == src_fd)
	{
		perror("mycy srcfile error");
		return ;
	}
	char ch ;
	dest_fd = open(dest , O_WRONLY | O_CREAT | O_EXCL  , 0777);
	if(dest_fd < 0)
	{
		//文件存在,判断是否覆盖
		printf("Over write ? Y/N\n");
		ch = getchar();
		if((ch == 'Y') || (ch == 'y'))
		{
			close(dest_fd);
			dest_fd = open(dest , O_WRONLY | O_TRUNC);
		}else
		{
			return  ;
		}
	}
	//文件不存在,直接创建成功
	char buffer[10] = {0} ;
	int ret ;
	while(1)
	{
		ret = read(src_fd , buffer , 10);
		write(dest_fd , buffer , ret);
		if(ret != 10)
			break;
	}

	close(dest_fd);
	close(src_fd);
}

void copy_directory(const char *src , const char *dest , const char *name)
{
	char buffer[265] = {0};
	char tmpbuffer[256] = {0};
	char tmpbuffer1[256] = {0};

	sprintf(buffer , "%s/%s" , dest , name);

	int ret ;
	struct stat  state ;
	DIR *dir = NULL ;
	struct dirent *entry = NULL ; 

	ret = stat(buffer , &state);
	if(ret == -1)
	{
		//目录不存在,copy
		ret = mkdir(buffer , 0777);
		printf("ret:%d buffer:%s\n" , ret , buffer);
		dir = opendir(src);
		if(NULL == dir)
		{
			perror("open dir error");
			return ;
		}

		while(1)
		{
			entry = readdir(dir);
			if(NULL == entry)
				break;
			if((strcmp(entry->d_name , ".")==0)||(strcmp(entry->d_name , "..")==0))
				continue ; 

			sprintf(tmpbuffer , "%s/%s" , buffer , entry->d_name);
			sprintf(tmpbuffer1 , "%s/%s" , src , entry->d_name);
			stat(tmpbuffer1 , &state);
			if(S_ISREG(state.st_mode))
			{
				copy_file( tmpbuffer1  ,   tmpbuffer);
			}
			if(S_ISDIR(state.st_mode))
			{
				copy_directory(tmpbuffer1 , buffer , entry->d_name);
				printf("*********** %s   ->  %s \n" , tmpbuffer1 , buffer);
			}
		}

	}
}

Linux系统编程---实现目录或者文件拷贝的更多相关文章

  1. Linux系统编程(1)——文件与I/O之C标准I/O函数与系统调用I/O

    Linux系统的I/O也就是一般所说的低级I/O--操作系统提供的基本IO服务,与os绑定,特定于Linux平台.而标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头 ...

  2. Linux系统编程(2)——文件与IO之系统调用与文件IO操作

    系统调用是指操作系统提供给用户程序的一组"特殊"接口,用户程序可以通过这组"特殊"接口来获得得操作系统内核提供的特殊服务.在linux中用户程序不能直接访部内核 ...

  3. linux系统编程快速定位头文件的技巧之强大的grep命令

    这个技巧来自于我的实际开发碰到的: inet_addr这个函数用于把ip地址转成网络字节序,他的原型:in_addr_t inet_addr(const char *cp); 返回值为一个in_add ...

  4. Linux系统编程(3)——文件与IO之fcntl函数

    linux文件I/O用:open.read.write.lseek以及close函数实现了文件的打开.读写等基本操作.fcntl函数可以根据文件描述词来操作文件. 用法: int fcntl(int ...

  5. Linux系统编程(5)——文件与IO之mmap函数

    mmap系统调用它本身提供了不同于一般对普通文件的访问方式,进程可以像读写内存一样对普通文件的操作.而Posix或系统V的共享内存IPC则纯粹用于共享目的,mmap()实现共享内存也是其主要应用之一. ...

  6. linux 系统监控某目录下文件及文件夹的变化

    inotifywait 是一个可以实时监控文件变动的工具,它利用linux内核中的inotify机制实现监控功能. 查看内核版本 [root@Oracle ~]# uname -r 2.6.32-22 ...

  7. Linux系统编程(4)——文件与IO之ioctl函数

    ioctl是设备驱动程序中对设备的I/O通道进行管理的函数.所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率.马达的转速等等.它的参数个数如下:int ioctl(int ...

  8. 《Linux系统编程(第2版)》

    <Linux系统编程(第2版)> 基本信息 作者: (美)Robert Love 译者: 祝洪凯 李妹芳 付途 出版社:人民邮电出版社 ISBN:9787115346353 上架时间:20 ...

  9. Linux C 程序 文件操作(Linux系统编程)(14)

    文件操作(Linux系统编程) 创建一个目录时,系统会自动创建两个目录.和.. C语言实现权限控制函数 #include<stdio.h> #include<stdlib.h> ...

随机推荐

  1. 【NOIP2016】天天爱跑步

    题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.«天天爱跑步»是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 个结点 ...

  2. 暗牧 (m)

    题目描述在 Dato3 的世界里,英雄们通过对量子力学的研究,发现了世界上其实存在着无数个位面——即是也被称作平行宇宙的存在.位面有无数多个,每个位面中包含 n 颗行星,由 n−1 个虫洞链接.同一个 ...

  3. Codeforces Round #407 (Div. 2)

    来自FallDream的博客,未经允许,请勿转载,谢谢. ------------------------------------------------------ A.Anastasia and ...

  4. C语言程序设计第二次作业—————顺序结构

    (一)改错题 1.输出带框文字:在屏幕上输出以下3行信息. ************* Welcome ************* 源程序 include int mian() { printf(&q ...

  5. PHP+JQuery+Ajax初始化网站基本信息(附源码)--PHP

    一.思路 为了保存用户会员信息的时间长一些,不局限于session的关闭.我们需要将用户信息保存在数据库中,前台每次登录都需要进行校验,来查看用看用户会员信息是否过期,如果没有过期,取出用户会员信息存 ...

  6. BI之SSIS入门最新版Visual Studio调试技巧

    简介 最近公司业务需要用到BI SSIS,SSIS是什么?"SSIS是Microsoft SQL Server Integration Services的简称,是生成高性能数据集成解决方案( ...

  7. JAX-RPC 与 JAX-WS 的比较

    引言 Web 服务已经出现很久了.首先是 SOAP,但 SOAP 仅描述消息的情况,然后是 WSDL,WSDL 并不会告诉您如何使用 Java™ 编写 Web 服务.在这种情况下,JAX-RPC 1. ...

  8. Hibernate给表和字段设置前后缀及分隔符

    在<一口一口吃掉Hibernate(一)--使用SchemaExport生成数据表>中介绍了如何生成数据表.但是这只是最基本的.hibernate在生成或者操作数据库时,会受一些限制.比如 ...

  9. 基本数据类型 异常 数组排序 JVM区域划分

               Day01 1.基本数据类型各占几个字节 Byte 1 short2 int4 long8 float4 double6 char2 boolean1 Byte b1=3,b2= ...

  10. Go 语言接口

    Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口. 实例 /* 定义接口 */ type interface_name in ...