linuxC i/o 小节2
文件的权限控制:
文件的权限有三个管理者,文件所有者,组用户,其他用户。一般情况下,有三种
基本的权限
1.r------------------------- 4读的权限
2.W------------------------ 2写的权限
3.X------------------------- 1可执行的权限
每一个管理者的最大权限为7(可读,可写,可执行)
最小的权限就是0(不能对这个文件做任何事)
-rwxrwxrwx.1 root root 0 5月 2322:11 example_64.c
这三类用户分别对应上面的三个RWX,从左向右依次为文件的所有者,组,以及其他
用户
当需要更改某个文件的一部分权限时,可以使用chmod/fchmod来修改文件的部分权
限。
例1.
例如赋给上述文件无任何权限: chmod 000 example_64.c
以下是这类函数的manpage (截取)
#include<sys/stat.h>
int chmod(constchar *path, mode_t mode);
intfchmod(int fildes, mode_t mode);
可见第一个函数有两个参数,分别是文件的路径名,以及给与的权限
第二个函数有两个参数分别为: 文件描述符,以及给与的权限
这里的权限不简单是1,2,4,7,0.。。。这里的权限参数有一个专门的列表
S_ISUID 04000 文件的(setuser-id on execution)位
S_ISGID 02000 文件的(setgroup-id on execution)位
S_ISVTX 01000 文件的sticky位
S_IRUSR(S_IREAD) 00400 文件所有者具可读取权限
S_IWUSR(S_IWRITE)00200 文件所有者具可写入权限
S_IXUSR(S_IEXEC) 00100 文件所有者具可执行权限
S_IRGRP 00040 用户组具可读取权限
S_IWGRP 00020 用户组具可写入权限
S_IXGRP 00010 用户组具可执行权限
S_IROTH 00004 其他用户具可读取权限
S_IWOTH 00002 其他用户具可写入权限
S_IXOTH 00001 其他用户具可执行权限
这里的权限值是八进制的
文件的输入输出(linux系统调用版本)
1.文件的创建,打开,关闭。
open()打开函数:
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int open(const char*pathname, int flags);
int open(constchar *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_tmode);
依然是manpage( )的截取包含了,需要的头文件和文件打开与创建函数的原型。
其接受的第一个参数为:文件的路径名称与文件名,第二个参数为文件打开的方式,特殊的当使用了O_CREAT就
是需要创建一个文件时,需要指定第三个参数MODE用来规定创建文件后的读写权限。
打开方式:
O_RDONLY : 以只读的方式打开
O_WRONLY : 以只写的方式打开
O_RDWR : 以制度并且可写的方式打开
这三种选项参数是互斥的,同样他们可以和下面的参数进行或运算,发挥更多的功能
O_CREAT: 如果文件不存在就建立一个这个文件
O_EXCL : 前提时创建选项以选,先检查有无这个文件,没有创建之,如果存在则打开出错
O_TRUNC: 如果文件存在且以可写的方式打开时,此标志会将文件长度清为0,说白了就是数据丢失了
O_APPEND: 写入文件的数据都会以追加的方式写入到文件的最后边
O_NOFOLLOW: 如果打开的是一个符号连接,那么打开的文件就会失败
O_DIRECTORY: 如果参数的文件并非为一目录,则会令打开文件失败
O_NONBLOCK| O_NDELAY; 以非阻塞的方式打开文件,对于open以及随后的对该文件的操作都会立即
返回,简言之只能有一个进程打开文件
O_SYNC :以同步的方式打开文件,任何对文件的修改都会阻塞直到物理磁盘上的数据同步以后才返回
2。creat( )函数
上边已经展示过文件创建函数的原形了,同样接受两个参数,第一个时文件的路径和名称,第二个就是创建文件的权
限。
3.close( )函数
#include<unistd.h>
int close(int fd);
这个函数很简单,他的功能和参数都很简单都只有一个,就是一个文件描述符,功能时用来关闭已经打开的文件。
文件的读写;
read( )读取函数
#include<unistd.h>
ssize_tread(int fd, void *buf, size_t count);
从指定文件中读取count个字节的内容到buf中,这个缓存最好足够大。
write()写入函数
#include<unistd.h>
ssize_twrite(int fd, const void *buf, size_t count);
将buf中的count个字节写入到fd中。
文件读写读写指针的移动 lseek()函数
#include<sys/types.h>
#include<unistd.h>
off_t lseek(intfd, off_t offset, int whence);
这个函数的作用就是用来控制文件读写的位置。
第一个参数,就是文件描述符,第二个参数为偏移量,具体的偏移方式是根据后面的参数决定的
第三个参数:用来指示文件的偏移方向
SEEK_SET :从文件开始处进行偏移
SEEK_CUR :从文件指针处开始偏移
SEEK_END :从文件的结尾处开始偏移
接着是一些其他有关函数:
dup,dup2,fcntl,ioctl,
1.dup()与dup2()函数:
#include<unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
惯例,先上manpage
第一个函数就是用来复制一个文件描述符:
接受一个老的文件描述符,返回一个新的文件描述符。
第二个函数功能也是用来复制文件描述符。
不过可以指定新的文件描述符
2,fcntl( )函数
#include<unistd.h>
#include <fcntl.h>
intfcntl(int fd, int cmd, ... /* arg */ );
可见这是一个变参函数,
这个系统调用主要用来对已经打开的文件描述符进行各种操作以改变以打开的各种属性
cmd的取值有以下几种:
F_DUPFD:此时DUP函数一样就是用来复制一个文件描述符
F_GETFD;设置与新的文件描述符相关的一些内容,用来获取close-on-exec标志,如果成功就返回文件标示符。
F_SETFD:设置新的文件描述符,其值为第三个参数
F_GETFL:此时函数用来获得文件的打开的方式
F_SETFL:此时函数设置文件打开方式,方式为第三个参数arg指定的方式(此时只能设置三种打开方式)
O_APPEND,O_NONBLOCK,O_ASYNC,追加,非阻塞,同步三种打开方式
同时这个参数还可以用来处理文件锁:
首先说明一下什么时文件锁:
文件锁:
这是一种结构体用来控制文件字节的更改权限
structflock{
包含如下内容:
这个表列出了文件锁的全部内容并且,列除了文件锁的选项内容。
为了锁整个文件一般设置:
l_start说明为0,l_whence说明为SEEK_SET,l_len设置为0.
下面列出了具体的参数:
F_SETLK: 此时函数被用来设置锁或释放锁,有三种选项。
F_SETLKW:此时函数被用来设置锁不同的是,当希望设置的锁因为存在其他的锁而被设置阻止时,该命令会等待向冲突的锁被释放。
F_GETLK: 此时第三个参数lock指向一个希望设置锁的属性的结构,如果锁能被设置,这个命令不真正的上一个锁,而是只修改lock的l_type为F_UNLCK,然后返回,如果存在一个或多个锁与希望设制的锁相冲突,则函数返回其中的一个锁的结构。
在函数执行这几个参数的时候,成功都返回0,失败都返回-1.
ioctl( ) 函数一般用来管理设备的参数,比如网卡信息等。
文件属性操作:
通常我们查看文件属性一般使用ls命令,其实这个命令调用了stat()函数
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
int stat(const char *pathname, struct stat *buf);
int fstat(int fd, structstat *buf);
intlstat(const char *pathname, struct stat *buf);
这三种函数都可以得到文件的信息,他们第一个参数一般接受一个文件描述符,或者文件路径,然后接受一个结构体,把文件的信息都存储进这个结构体中。
这里包含了由一系列的文件状态信息;
设备编号,I节点,更改时间,用户ID,组ID等等一系列的文件的信息
其他文件处理函数:
设置文件属性:hmod/fchmod:用于修改文件的存取权限,见之前的更改文件权限信息总结
chown/fchown/lchown:
用来修改文件的用户ID和组ID.
#include<unistd.h>
int chown(const char*pathname, uid_t owner, gid_t group);
intfchown(int fd, uid_t owner, gid_t group);
int lchown(const char *pathname, uid_t owner, gid_t group);
比如需要修改一个文件的组ID与用户ID,将他们都改成root目录下
eg.
chown root:root XXXXX
#include<unistd.h>
#include<sys/types.h>
int truncate(constchar *path, off_t length);
intftruncate(int fd, off_t length);
truncate/ftruncate函数用来修改文件的大小,如果文件的大小不够大就产生文件内容丢失,如果文件将被扩大那么文件多余的部分将被置为0.
utime()更改文件被修改时间的函数:
#include<sys/types.h>
#include<utime.h>
int utime(const char*filename, const struct utimbuf *times);
#include <sys/time.h>
intutimes(const char *filename, const struct timeval times[2]);
和更改权限类似,此函数也是接受一个路径,和一个结构体,这个结构体里有两个时间,一个是存取时间,一个是最后被修改的时间。
structutimbuf {
time_tactime ; 存取的时间
time_tmodtime; 最后被修改的时间
}
在使用这种函数时,先生命一个结构体,然后传参使用。
文件的移动与删除:
在LINUX中文件的移动与删除都是系统调用
#include<stdio.h>
int rename(const char*oldpath, const char *newpath);
很简单将一个文件移动到一个新的地方
#include<unistd.h>
int unlink(const char*pathname);
这里只接受一个目录,然后删除它。
#include<stdio.h>
int remove(const char*pathname);
同上也是删除一个目录,他与上边的区别还有待确认
获取目录的信息;
opendir,readdir,closedir
#include<sys/types.h>
DIR*opendir(const char *name);
打开指定的文件名,返回一个目录流。如果失败就返回NULL
#include<dirent.h>
structdirent *readdir(DIR *dirp);
从参数dir所指向的目录中读取目录项的信息,返回一个结构体指针。
#include<sys/types.h>
#include<dirent.h>
intclosedir(DIR *dirp);
用来关闭参数dirp指向的目录,成功后返回0,失败惯例返回-1.