Unix/Linux基本文件操作—之cp命令

一、问题描述
基于系统调用的操作方法与通过C语言标准库函数的方法相比,运行机制有着本质的区别。
这里使用两种方法编写程序实现相同功能的程序,来对比他们之间的不同。

程序实现【文件】复制命令"cp"的功能 :

二 、实现代码

BUG 描述: 当参数1存在的情况下,而参数2是路径 而没有表明是文件 这时的cp命令会失败!以下代码在判断后面提示无论目录书中任何路径必须用户自定义一个存在或不存在的文件名。

*****************************************************
copyright (C), 2014-2015, Lighting Studio. Co.,     Ltd. 
File name:
Author:Jerey_Jobs    Version:0.1    Date: 
Description:
Funcion List: 
*****************************************************/

//使用标准i/o库实现

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#define SIZE_BUF 1024

int main(int argc,char *argv[])
{
    FILE *fds,*fdt;                                     /*用于打开当前用户指定目录下的文件*/
    char answer = 'n';                                  /*用于当路径或文件不存在时,作为标志位 提示用户是否要退出此程序 重新输入正确的路径以及文件*/
    
	ssize_t size = -1;                                  //用于接受fread()或fwrite()的返回值

	char buf[SIZE_BUF];                                 //定义缓冲区 大小:1KB

	struct timeval tv;                                  //创建用于访问库函数time.h的结构体变量

	long original_time,final_time;                      //用于计算整个程序的运行时长
	gettimeofday(&tv,NULL);                             //时间采集函数,可精确到微妙级

	original_time = tv.tv_sec;                          //这里采用秒级

	if(argc !=3)
	{
    	printf("您输入了不正确的参数!\n");
    	exit(-1);                                       //参数必须是3个  包括./*.out
	}

	if((fds = fopen(argv[1],"rb")) == NULL)             //以读二进制的形式打开源路径文件
	{
    	printf("Usage:cp(fun) 源文件: %s 不存在!\n",argv[1]);
	}
	fclose(fds);

	if((fdt = fopen(argv[2],"wb+")) == NULL)            //目标文件不存在则创建
	{
    	int ret;
    	printf("文件路径:'%'s不存在,是否继续(Y(y)/N(n))?\n",argv[2]);
    	scanf("%c",&answer);
    	if(answer != 'y')
    	{
        	return -1;                                  //告诉系统我出错了
    	}
    	else
    	{
        	printf("请输入正确的目标路径名(必须有文件名):\n:");
        	do
        	{
            	ret = scanf("%s",argv[2]);
            	fdt = fopen(argv[2],"wb+");
        	}while(ret == 1 && NULL == fdt);
            	//fdt = fopen(argv[2],"wb+");         
    	}
	}

	fds = fopen(argv[1],"rb");                          //如果没出错
	if(fds == NULL)
	{
    	printf("该文件不存在或路径错误!\n");
    	return -1;
	}
	else
	{
    	while(size)
    	{
        	size = fread(buf,sizeof(char),SIZE_BUF,fds);
        	if(size == -1)
        	{
            	printf("读取文件失败!\n");
        	}
        	else
        	{
            	if(size > 0)
            	{
                	fwrite(buf,sizeof(char),SIZE_BUF,fdt);
            	}
        	}
    	}
	}
	fclose(fdt);
	fclose(fds);

	gettimeofday(&tv,NULL);
	final_time = tv.tv_sec;

	printf("该程序的运行时间为:%u s\n",final_time - original_time);
	return EXIT_SUCCESS;
}
cp功能 ——系统调用实现:
/*****************************************************
copyright (C), 2014-2015, Lighting Studio. Co.,     Ltd. 
File name:
Author:Jerey_Jobs    Version:0.1    Date: 
Description:
Funcion List: 
*****************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>

#define SIZE_BUF 1024

int main(int argc,char *argv[])
{
    int fds,fdt;
    ssize_t size = -1;
    char buf[SIZE_BUF]; 
    char answer = 'n';

	struct timeval tv;

	long original_time,final_time;
	gettimeofday(&tv,NULL);

	original_time = tv.tv_usec;
	if(argc !=3)
	{
    	printf("您输入了不正确的参数!\n");
    	exit(0);
	}

	if((fds = open(argv[1],O_RDONLY | O_EXCL)) == -1)
	{
    	printf("Usage:cp(fun) 源文件: %s不存在!\n",argv[1]);
	}
	close(fds);

	if((fdt = open(argv[2] , O_WRONLY | O_CREAT | O_EXCL , 00700)) == -1)
	{
    	int ret;
    	printf("文件路径:'%s'不存在,是否继续(Y(y)/N(n))?\n",argv[2]);
    	scanf("%c",&answer);
    	if(answer != 'y')
    	{
        	return -1;
    	}
    	else
    	{
        	printf("请输入正确的目标路径名(必须有文件名):\n:");
        	do
        	{
            	ret = scanf("%s",argv[2]);
            	fdt = open(argv[2] , O_WRONLY | O_CREAT | O_EXCL , 00700);
        	}while(ret == 1 && fdt == -1);
    	}
	}

	fds = open(argv[1] , O_RDONLY);
	if(fds == -1)
	{
    	printf("该文件不存在,或路径错误!\n");
    	return -1;
	}
	else
	{
    	while(size)
    	{
        	size = read(fds,buf,SIZE_BUF);
        	if(size == -1)
        	{
            	printf("读取文件失败!\n");
        	}
        	else if(size > 0)
        	{
            	write(fdt , buf , size);
        	}
    	}
	}
	close(fdt);
	close(fds);

	gettimeofday(&tv,NULL);
	final_time = tv.tv_usec;

	printf("该程序的运行时间为:%u us\n",final_time - original_time);

	return EXIT_SUCCESS;
}

三、运行结果
Unix/Linux基本文件操作—之cp命令Unix/Linux基本文件操作—之cp命令
利用内置软件打开复制过后的PDF文件:打开成功

Unix/Linux基本文件操作—之cp命令