最近在学习linux环境编程,用学到的文件编程写了一个模拟命令 cp的代码,当然有很多不足之处,但是基本功能都实现了。 文件编程用到的函数不明白的可以百度。其实学这个也只是为了加深对Linux系统的理解。代码有什么问题请回复,方便大家交流学习。
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#define BUFFERSIZE 10000
int isdir(char *src)
{
struct stat is_dir;
//lstat函数把源文件名的文件类型和存储权限传给stat结构体中的st_mode变量
lstat(src, &is_dir);
//S_ISDIR函数判断该文件是不是目录文件
if(S_ISDIR(is_dir.st_mode))
{
return 1;
}
return 0;
}
//文件拷贝到文件 或文件拷贝到目录下
int copyF2F(char *src_file, char *dest_file)
{
int in_fd, out_fd, n_chars;
char buf[BUFFERSIZE];
//如果目的地址是目录,则默认在该目录下创建一个与源文件同名的文件
if(isdir(dest_file))
{
char c;
char temp[10] = {'\0'};
char r_temp[10] = {'\0'};
int n = strlen(src_file);
int m = 0;
//记录源文件最后一个'/'之后的内容
while((c = src_file[n-1]) != '/')
{
//用temp数组存下来
temp[m] = c;
m++;
n--;
}
int j = 0;
//由于temp数组存下来的字符是反的,所以反转一下字符
for(int i = strlen(temp)-1; i >=0; i--)
{
r_temp[j] = temp[i];
j++;
}
r_temp[j] = '\0';
//将源文件的最后的文件名和目的文件目录拼接起来
strcat(dest_file, r_temp);
}
//打开源文件,获取到文件描述符,失败返回-1
if((in_fd = open(src_file, O_RDONLY)) == -1)
{
printf("%s is error", src_file);
return 1;
}
//打开目的文件,获取文件描述符,失败返回-1,注意此时需要写的权限所以参数应该有O_WRONLY,并且如果不存在需要有权限创建。具体的函数用法参照上之前写的文件I/O编程博客
if((out_fd = open(dest_file, O_WRONLY | O_CREAT, 0644)) == -1)
{
printf("open is error");
return 1;
}
//现在源文件和目的文件的文件描述符都获取到了,开始复制。read函数第一个参数代表要读出的文件描述符,第二个参数代表存数据的数组首地址,第三个参数代表要读出多少个字节。读取成功返回读取的字节数,有错返回-1
if((n_chars = read(in_fd, buf, BUFFERSIZE))>0)
{
//写入目标文件中。错误返回-1
if(write(out_fd, buf, n_chars)<0 )
{
printf("%s write error", dest_file);
return 1;
}
}
//close函数用于关闭文件,打开文件了记得关
if(close(in_fd) == -1 || close(out_fd) == -1)
{
printf("error");
return 1;
}
return 0;
}
//目录拷贝到目录下
int copyD2D(char *src_dir, char *dest_dir)
{
//用来获取打开文件目录时返回的指针
DIR *dp = NULL;
struct dirent *dirp;
char tempDest[256];
char tempSrc[256];
strcpy(tempDest, dest_dir);
strcpy(tempSrc, src_dir);
//opendir打开文件目录,返回NULL代表打开失败
if((dp = opendir(src_dir)) == NULL)
{
return 1;
}
else
{
//readdir()返回参数dir目录流的下个目录进入点
while((dirp = readdir(dp)))
{
if(isdir(dirp->d_name)) //d_name是文件的名称
{
strcat(tempDest, dirp->d_name);
strcat(tempSrc, dirp->d_name);
//将目录中的文件拷贝到另一个目录中
copyF2F(tempSrc, tempDest);
//把tempDest和tempSrc重新初始化成目录名
strcpy(tempDest, dest_dir);
strcpy(tempSrc, src_dir);
}
}
//关闭打开的目录
closedir(dp);
return 0;
}
}
int main(int argc, char * argv[])
{
int c, flag = 0;
while((c = getopt(argc, argv, "rRls"))!=-1)
{
switch(c)
{
//选项为-R或-r时,执行目录之间的拷贝
case 'R':
case 'r':
copyD2D(argv[2], argv[3]);
flag = 1;
break;
//选项为-l时,创建链接
case 'l':
if(isdir(argv[2]))
{
printf("dir can't create a link");
exit(1);
}
if(link(argv[2], argv[3])==0)
{
return 0;
}
else
{
printf("create a link failed");
}
flag = 1;
break;
case 's':
if(isdir(argv[2]))
{
printf("dir can't create a symlink");
}
if((symlink(argv[2], argv[3])) == 0)
{
return 0;
}
else
{
printf("create a symlink failed");
}
flag = 1;
break;
}
}
if(flag == 0)
{
copyF2F(argv[1], argv[2]);
}
return 0;
}

本文介绍了一个简单的Linux环境下模拟cp命令的程序实现。该程序能够复制文件到文件或目录,也能处理目录间的复制,并支持基本的命令行选项如-r、-l和-s。通过此程序加深了对Linux文件操作的理解。
7万+

被折叠的 条评论
为什么被折叠?



