Linux系统编程-文件操作
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
最基本的访问文件方法是:使用read()和write()系统调用。在一个文件能被访问之前,必须通过open()
或者creat()系统调用打开它,一旦使用完毕,则用close()系统调用来关闭文件。
1.open
#include
#include
#include
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
返回值:成功返回新分配的文件描述符,出错返回-1并设置errno
eg:
int fd;
fd = open("/home/kidd/aaa",O_RDONLY);
if(fd == -1)
/*error*/
pathname 参数是要打开或创建的文件名,和fopen一样,pathname 既可以是相对路径也可以是绝对路径。
flags参数有一系列常数值可供选择,可以同时选择多个常数用按位或运算符连接起来,
所以这些常数的宏定义都以O_开头,表示or 。
以下三个三先一:
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 可读可写打开
以下可多选(以或的形式)(进行按位或运算,用以修改打开文件请求的行为)
O_APPEND
表示追加。如果文件已有内容,这次打开文件所写的数据附加到文件的末尾而不覆盖原来的内容。
(文件将以追加模式下打开。就是说,在每次写操作之前,文件位置指针将被置于文件末尾,即使
在进程刚刚完成写操作并改变文件位置指针之后,如有另一进程开始写操作,情形也是如此。)O_CREAT
若此文件不存在则由(内核来)创建它。使用此选项时需要提供第三个参数mode,表示该文件的访问权限。
有0666。如果文件已存在,本标志无效,除非给出了O_EXCL标志。
当文件创建时,mode参数提供新建文件的权限。系统并不在该次打开文件时检查权限,所以你可以进行相反的操作,例如设置文件为只读权限,但却在打开文件后进行写操作。最终写入磁盘的权限位还需让mode参数与用户文件创建的掩码(即umask)做按位与操作后来确定。 umask 022,mode 0666,文件权限为0644(0666&~022)
O_EXCL
如果同时指定了O_CREAT,并且文件已存在,则出错返回。(用来防止文件创建时出现单键竞争。)O_TRUNC
如果文件已存在且为普通文件,并且以只写或可读可写方式打开,则将其长度截断(Truncate)为0字节。
对于FIFO或者终端设备,该参数被忽略。在其他文件类型上则没有定义。因为截断文件需要写权限,所以O_TRUNC和O_RDONLY同时使用也是没有定义的。
eg: int fd;
fd = open("/home/teach/pearl", O_WRONLY|O_TRUNC);
if(fd == -1)
/*error*/
O_NONBLOCK
对于设备文件,以O_NONBLOCK方式打开可以做非阻塞I/O (Nonblock I/O )。
open()及任何其他操作都不会使该进程在I/O中阻塞(sleep)。这种情况可只用于FIFO。
思考:新文件的所有者是谁?新文件的权限是啥?
例子:下面的代码对文件file进行写操作。如果文件不存在,且假定umask值为022,将建立权限值为0644的文件(即使mode参数指定为0664)。如果文件已存在,它的长度会被截断成0。
int fd;
fd =
open(file,O_WRONLY|O_CREAT|O_TRUNC,S_IWUSR|S_IRUSR|S_IWGRP|S_IRGRP|S_IROTH);
if(fd == -1)
/*error*/
补充:mode参数可以是以下内容:
S_IRWXU 所有者拥有读写和执行权限
S_IRUSR 所有者拥有读权限
S_IWUSR 所有者拥有写权限
S_IXUSR 所有者拥有执行权限
S_IRWXG 组拥有读写和执行权限
S_IRGRP 组拥有读权限
S_IWGRP 组拥有写权限
S_IXGRP 组拥有执行权限
S_IRWXO 任何其他人都有读写和执行权限
S_IROTH 任何其他人都有读权限
S_IWOTH 任何其他人都有写权限
S_IXOTH 任何其他人都有执行权限
函数与C 标准I/O 库的fopen函数有些细微的区别:
1 以可写的方式fopen一个文件时,如果文件不存在会自动创建,而open一个文件时必须明
确指定O_CREAT才会创建文件,否则文件不存在就出错返回。
2 以w 或w+方式fopen一个文件时,如果文件已存在就截断为0 字节,而open一个文件时必须
明确指定O_TRUNC才会截断文件,否则直接在原来的数据上改写。
第三个参数mode指定文件权限,可以用八进制数表示,比如0644表示-rw-r--r--
实验
1.umask
0022
用touch命令创建一个文件时,创建权限是0666,而touch进程继承了Shell进程的umask掩码,
所以最终的文件权限是0666&~022=0644 。
2.touch aaa.c
ll aaa.c
-rw-r--r-- 1 root root 0 01-30 14:18 aaa.c
同样道理,用gcc 编译生成一个可执行文件时,创建权限是0777,而最终的文件权限
是0777&~022=0755 。
gcc aaa.c
ll a.out
-rwxr-xr-x 1 root root 4943 01-30 14:20 a.out
3.umask 0
再重复上述实验
==========================================================