在开始之前,我们先确定这次编程的主要目的——
确定了主要目的之后,先看文件在linux系统中的有关概念
**- Linux系统中,文件的准确定义是不包含有任何其他结构的字符流。
- Linux系统提供的文件系统,是树形层次结构系统。
- Linux支持多种文件系统,最常用的文件系统是ext2系统。
- Linux系统的文件属性主要包括文件类型和文件权限两个方面**
那么我们若要实现拷贝功能,不仅要拷贝文件内容,而且要拷贝文件属性。
以下是linux系统中文件的主要类型,在此我们只实现基础的普通文件的拷贝。
以下是linux系统中文件权限的说明
*对于Linux系统中的文件来说,它的权限可以分为4种:可读取(Readable)、可写入(Writable)、可执行(eXecute)和无权限,分别用r、w、x和-表示。
Linux系统按文件所有者、文件所有者同组用户和其它用户三类规定不同的文件访问权限。
显示的作为权限的10个字符,可分为四部分:
第一位:一般表示文件类型。
第二位到第四位(第一组rwx):表示文件所有者的访问权限。
第五位到第七位(第二组rwx):表示文件所有者同组用户的访问权限。
第八位到第十位(第三组rwx):表示其他用户的访问权限。*
linux文件的其他属性如下
struct stat {
mode_t st_mode; //文件对应的模式,文件,目录等
ino_t st_ino; //inode节点号
dev_t st_dev; //设备号码
dev_t st_rdev; //特殊设备号码
nlink_t st_nlink; //文件的连接数
uid_t st_uid; //文件所有者
gid_t st_gid; //文件所有者对应的组
off_t st_size; //普通文件,对应的文件字节数
time_t st_atime; //文件最后被访问的时间
time_t st_mtime; //文件内容最后被修改的时间
time_t st_ctime; //文件状态改变时间
blksize_t st_blksize; //文件内容对应的块大小
blkcnt_t st_blocks; //伟建内容对应的块数量
};
如果要获得文件的其他属性,可以使用stat函数或者fstat函数。
stat函数用来判断没有打开的文件,而fstat函数用来判断打开的文件。使用较多的属性是st_mode,通过此属性可以判断给定的文件是一个普通文件还是其他文件类型
不带缓存的文件I/O操作,又称系统调用I/O操作,符合POSIX标准,设计的程序能在兼容POSIX标准的系统间方便地移植
POSIX文件函数如下
那么到此我们实现cp的基本知识已经具备。
c语言代码如下
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[], char *env[])
{
struct stat stc,stt;
int i;
char *tmp,buf[65535],src[1024],aim[1024];
int fps,tar;//文件
realpath(argv[1],src);
realpath(argv[2],aim);
stat(src,&stc);
if (S_ISDIR(stc.st_mode))//是目录
{perror("源文件是目录形式!");exit(1);}
else
{
fps=open(src,O_RDONLY);
if(fps==-1)
{perror("源文件打开失败!");exit(1);}
//read(fps,buf,stc.st_size);
}
stat(aim,&stt);
if (S_ISDIR(stt.st_mode))//第二参数是目录
{
tmp=strrchr(src,'/');//查找到最后一个/
strcat(aim,tmp);//组合获得原有文件名
}
tar=open(aim,O_CREAT|O_RDWR,stc.st_mode);
if(tar==-1)
{perror("目标文件打开(创建)失败!");exit(1);}
while((i=read(fps,buf,65535))>0)
{write(tar,buf,i);
}
close(fps);
close(tar);
return 0;
}
将编写后的可执行文件放入/usr/bin下便可在bash中调用。
经过这次的学习,可以了解到不带缓存的文件i/o操作(系统调用),那么我由这次编程联想到进程之间的管道(pipe)通信。pipe也很巧合的使用了不带缓存的文件i/o操作。那么两者间的原理是一样的吗?在之后的学习中,查阅相关的资料后我再论述。