1、文件的访问权限控制 chmod/fchmod
#include
int chmod(const char *path, mode_t mode); ==>path ,文件名;mode,文件权限
int fchmod(int fd, mode_t mode); ==>fd,文件描述符
两者的区别:chmod 以文件名作为第一个参数,fchmod以文件描述符作为第一个参数。
权限更改成功返回0,失败返回-1,错误代码存于系统预定义变量errno中。(利用chmod函数可以实现自己的简化版chmod命令)
cat my_chmod.c
#include
#include
#include
#include
int main(int argc,char ** argv)
{
int mode; //权限
int mode_u; //所有者的权限
int mode_g; //所属组的权限
int mode_o; //其他用户的权限
char *path;
/*检查参数个数的合法性*/
if(argc < 3) {
printf("%s \n",argv[0]);
exit(0);
}
/*获取命令行参数*/
mode = atoi(argv[1]);//atoi将字符串转换为整数
if (mode > 777 || mode < 0){
printf("mode num error!\n");
exit(0);
}
mode_u = mode / 100; //取百位确定用户权限
mode_g = (mode - (mode_u*100)) / 10; //取十位确定组权限
mode_o = mode - (mode_u*100) - (mode_g*10); //八进制转换
path = argv[2];
if ( chmod(path,mode) == -1){
perror("chmod error");
exit(1);
}
return 0;
}
gcc my_chmod.c -o my_chmod
./my_chmod 744 my_ch
ls -l my_ch
--wxr-x--T 1 linux linux 7122 2008-12-12 21:15 my_ch
2、文件的输入输出
文件的输入输出函数有,creat、open、close、read、write和lseek等。
它们这些系统调用都是使用文件描述符来标识文件,(文件描述符是UNIX/Linux特有的),对内核而言,所有打开的文件都由文件描述符标识。
文件描述符是一个非负整数。在读写一个文件前,需要现调用open或creat函数打开文件,成功执行这两个函数都将返回一个文件描述符。在对文件执行读写操作时,将其作为参数传递给read或write。文件描述符的取值范围在0~NR—OPEN之间,Linux中NR—OPEN为255,也就是说每个程序最多只能打开256个文件。
(1)open和creat函数 open和creat系统调用用来打开或创建一个文件
函数原型为:
#include
#include
#include
int open(const char *pathname, int flags); ==>pathname是要打开或创建的含路径的文件名,第二个参数flags表示打开文件的方式。
int open(const char *pathname, int flags, mode_t mode); ==> 当且仅当第二个参数使用了O—CREAT时,需要使用第三个参数mode,以说明新文件的存取权限。(新文件的实际存取权限是mode与umask按照(mode& ~umask)运算以后的结果)
int creat(const char *pathname, mode_t mode); ==>第一个参数是要打开或创建的文件名,如果pathname指向的文件不存在,则创建一个新文件;如果指向的文件存在,则原文件被新文件覆盖。
打开文件的方式:
O—RDONLY、O—WRONLY、O—RDWR 分别以只读、只写或可读可写的方式打开。
这三种打开方式是互斥的,不能同时以两种或三种方式打开文件,但可以分别与下列标志进行或运算。
O—CREAT:若文件不存在则自动建立该文件,只有在此时需要用到第三个参数mode,以说明新文件的存取权限。
0—EXCL: 如果O—CREAT也被设置,此指令会去检查文件是否存在。文件若不存在则创建,若存在则导致打开文件出错。
O—TRUNC:若文件存在并且以可写的方式打开时,此标志会将文件长度清0,即源文件中保存的数据将丢失,但文件属性不变。
O—APPEND:所写入的数据会以追加的方式加入到文件后面。
O—SYNC:以同步的方式打开文件,任何对文件的修改都会阻塞直到物理磁盘上的数据同步以后才返回。
O—NOFOLLOW:如果参数pathname所指的文件为一符号链接,则会令打开文件失败。
O—DIRECTORY:如果参数pathname所指的文件并非一目录,则会令打开文件失败。
O—NONBLOCK或O—NDELAY:以非阻塞的方式打开文件,对于open及随后的对该文件的操作,都会立即返回。
(2)close函数 close系统调用用来关闭一个已经打开的文件。
#include
int close(int fd);
用open系统调用创建一个新文件。
cat my_create.c
#include
#include
#include
#include
#include
#include
int main()
{
int fd;
if((fd = open("example.c",O_CREAT|O_EXCL,S_IRUSR| S_IWUSR)) == -1){ ==>
perror("open"); ==>如果要从错误代码中获取相应的错误描述,可以把该行注释掉,添加“printf("open:%s with errno:%d\n",strerror(errno),errno);”
exit(1);
}else {
printf("Create file success\n");
}
close(fd);
return 0;
}
./my_create
Create file success
ls
example.c my_ch my_chmod.c my_create my_create.c myls
ls -l example.c
-rw------- 1 linux linux 0 2008-12-13 16:31 example.c
3、文件的读写
(1)read函数 read系统调用用来从打开的文件中读取数据。
#include
ssize_t read(int fd, void *buf, size_t count); ==>从文件描述符fd所指向的文件中读取count个字节的数据到buf所指向的缓存中。
count为0,则read()不会读取数据,只返回0。返回值表示实际读取到的字节数。如果返回0,表示已达到文件尾或者是无可读取数据。文件读写指针会随读取到的字节移动。
当错误发生时则返回-1,错误代码存入errno中。
(2)write函数 write系统调用用来将数据写入已打开的文件中。
#include
ssize_t write(int fd, const void *buf, size_t count);
4、文件读写指针的移动
lseek系统调用用来移动文件读写指针的位置。
#include
#include
off_t lseek(int fd, off_t offset, int whence); ==>offset为根据参数whence来移动读写位置的位移数。whence有3种取值:
SEEK—SET从文件开始处计算偏移量,文件指针到文件开始处的距离为offset。
SEEK—CUR从文件指针的当前位置开始计算偏移量,文件指针值等于当前指针值加上offset的值,offset允许取负数。
SEEK—END 从文件结尾处开始计算偏移量,文件指针值等于当前指针值加上offset的值,offset允许取负数。
lseek(int fildes,0,SEEK_SET); 将文件读写指针移动到文件开头
lseek(int fildes,0,SEEK_END); 将文件读写指针移动到文件结尾
lseek(int fildes,0,SEEK_CUR); 获取文件读写指针当前的位置(相对于文件头的偏离)
5、dup、dup2
dup与dup2函数常用于实现输入、输出的重定向。(将文件的描述符赋值给其他变量,如将文件复制到标准输入输出中)
#include
int dup(int oldfd);
int dup2(int oldfd, int newfd);
dup函数用于复制指定的文件描述符。函数返回的新描述符是当前进程最小的未使用的描述符。
dup2函数也是用户复制指定的文件描述符,只是参数与dup函数存在不同。如果新的文件描述符已经打开(newfd),将会先关闭新的文件描述符。
在linux中还定义了如下的宏,方便程序员对标准输入、输出和错误输出进行控制。
STDIN—FILENO:标准输入,其值为0。
STDOUT—FILENO:标准输出,其值为1。
STDERR—FILENO:标准错误输出,其值为2。
错误信息:
EBADF:oldfd不是打开的文件描述符,或newfd超出了文件描述符允许的范围。
EBUSY:在使用open函数和dup函数时发生了冲突,dup2函数返回该错误。
EMFILE:进程打开文件达到上限。
fcntl系统调用可以用来对已打开的文件描述符进行各种控制操作以改变已打开文件的各种属性,其函数原型如下:
#include
#include
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
阅读(1520) | 评论(0) | 转发(1) |