当前位置:文档之家› Linux系统编程-文件操作

Linux系统编程-文件操作

最基本的访问文件方法是:使用read()和write()系统调用。

在一个文件能被访问之前,必须通过open()或者creat()系统调用打开它,一旦使用完毕,则用close()系统调用来关闭文件。

1.open#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);返回值:成功返回新分配的文件描述符,出错返回-1并设置errnoeg: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.umask0022用touch命令创建一个文件时,创建权限是0666,而touch进程继承了Shell进程的umask掩码,所以最终的文件权限是0666&~022=0644 。

2.touch aaa.cll aaa.c-rw-r--r-- 1 root root 0 01-30 14:18 aaa.c同样道理,用gcc 编译生成一个可执行文件时,创建权限是0777,而最终的文件权限是0777&~022=0755 。

gcc aaa.cll a.out-rwxr-xr-x 1 root root 4943 01-30 14:20 a.out3.umask 0再重复上述实验==========================================================Given a pathname for a file, open() returns a file descriptor, a small, non-negative integer for use insubsequent system calls (read(2), write(2), lseek(2),fcntl(2), etc.). The file descriptor returned by a suc-cessful call will be the lowest-numbered file descriptornot currently open for the process.The parameter flags must include one of the following access modes: O_RDONLY, O_WRONLY, or O_RDWR. Theserequest opening the file read-only, write-only, orread/write, respectively.In addition, zero or more file creation flags and file status flags can be bitwise-or’d in flags. The filecreation flags are O_CREAT, O_EXCL, O_NOCTTY, andO_TRUNC. The file status flags are all of the remainingflags listed below. The distinction between these twogroups of flags is that the file status flags can beretrieved and (in some cases) modified using fcntl(2).The full list of file creation flags and file statusflags is as follows:O_APPENDThe file is opened in append mode. Before eachwrite(), the file offset is positioned at the endof the file, as if with lseek(). O_APPEND maylead to corrupted files on NFS file systems ifmore than one process appends data to a file atonce. This is because NFS does not supportappending to a file, so the client kernel has tosimulate it, which can’t be done without a racecondition.O_CREATIf the file does not exist it will be created.The owner (user ID) of the file is set to theeffective user ID of the process. The group own-ership (group ID) is set either to the effectivegroup ID of the process or to the group ID of theparent directory (depending on filesystem typeand mount options, and the mode of the parentdirectory, see, e.g., the mount options bsdgroupsand sysvgroups of the ext2 filesystem, asdescribed in mount(8)).O_EXCLWhen used with O_CREAT, if the file alreadyexists it is an error and the open() will fail.In this context, a symbolic link exists, regard-less of where it points to. O_EXCL is broken onNFS file systems; programs which rely on it forperforming locking tasks will contain a race con-dition. The solution for performing atomic filelocking using a lockfile is to create a uniquefile on the same file system (e.g., incorporatinghostname and pid), use link(2) to make a link tothe lockfile. If link() returns 0, the lock issuccessful. Otherwise, use stat(2) on the uniquefile to check if its link count has increased to2, in which case the lock is also successful.O_NONBLOCK or O_NDELAYWhen possible, the file is opened in non-blockingmode. Neither the open() nor any subsequent oper-ations on the file descriptor which is returnedwill cause the calling process to wait. For thehandling of FIFOs (named pipes), see alsofifo(7). For a discussion of the effect ofO_NONBLOCK in conjunction with mandatory filelocks and with file leases, see fcntl(2).O_TRUNCIf the file already exists and is a regular fileand the open mode allows writing (i.e., is O_RDWRor O_WRONLY) it will be truncated to length 0.If the file is a FIFO or terminal device file,the O_TRUNC flag is ignored. Otherwise the effectof O_TRUNC is unspecified.The argument mode specifies the permissions to use in case a new file is created. It is modified by the pro- cess’s umask in the usual way: the permissions of the created file are (mode & ~umask). Note that this mode only applies to future accesses of the newly created file; the open() call that creates a read-only file may well return a read/write file descriptor.RETURN VALUEopen() and creat() return the new file descriptor, or -1 if an error occurred (in which case, errno is set appro- priately).ERRORSEACCESThe requested access to the file is not allowed,or search permission is denied for one of thedirectories in the path prefix of pathname, orthe file did not exist yet and write access tothe parent directory is not allowed. (See alsopath_resolution(2).)EEXISTpathname already exists and O_CREAT and O_EXCLwere used.EFAULTpathname points outside your accessible address space.creat() is equivalent to open() with flags equal toO_CREAT|O_WRONLY|O_TRUNC.creat("aa.c",0666); open("aa.c",O_CREAT|O_WRONLY|O_TRUNC,0666);2.close#include <unistd.h>int close(int fd);返回值:成功返回0 ,出错返回-1并设置errnoclose()调用解除了已打开的文件描述符的关联,并分离进程和文件的关联。

相关主题