分类: LINUX
2011-06-09 11:10:53
open 函数用于打开和创建文件。以下是 open 函数的简单描述
#include <fcntl.h>
int open(const char *pathname, int oflag, ... /* mode_t mode */);
返回值:成功则返回文件描述符,否则返回 -1
对于 open 函数来说,第三个参数(...)仅当创建新文件时才使用,用于指定文件的访问权限位(access permission bits)。pathname 是待打开/创建文件的路径名(如 C:/cpp/a.cpp);oflag 用于指定文件的打开/创建模式,这个参数可由以下常量(定义于 fcntl.h)通过逻辑或构成。
O_RDONLY 只读模式
O_WRONLY 只写模式
O_RDWR 读写模式
打开/创建文件时,至少得使用上述三个常量中的一个。以下常量是选用的:
O_APPEND 每次写操作都写入文件的末尾
O_CREAT 如果指定文件不存在,则创建这个文件
O_EXCL 如果要创建的文件已存在,则返回 -1,并且修改 errno 的值
O_TRUNC 如果文件存在,并且以只写/读写方式打开,则清空文件全部内容
O_NOCTTY 如果路径名指向终端设备,不要把这个设备用作控制终端。
O_NONBLOCK 如果路径名指向 FIFO/块文件/字符文件,则把文件的打开和后继 I/O
设置为非阻塞模式(nonblocking mode)
以下三个常量同样是选用的,它们用于同步输入输出
O_DSYNC 等待物理 I/O 结束后再 write。在不影响读取新写入的数据的
前提下,不等待文件属性更新。
O_RSYNC read 等待所有写入同一区域的写操作完成后再进行
O_SYNC 等待物理 I/O 结束后再 write,包括更新文件属性的 I/O
open 返回的文件描述符一定是最小的未被使用的描述符。
如果 NAME_MAX(文件名最大长度,不包括'\0')是 14,而我们想在当前目录下创建文件名长度超过 14 字节的文件,早期的 System V 系统(如 SVR2)会截断超出部分,只保留前 14 个字节;而由 BSD 衍生的(BSD-derived)系统会返回错误信息,并且把 errno 置为 ENAMETOOLONG。
POSIX.1 引入常量 _POSIX_NO_TRUNC 用于决定是否截断长文件名/长路径名。如果_POSIX_NO_TRUNC 设定为禁止截断,并且路径名长度超过 PATH_MAX(包括 '\0'),或者组成路径名的任意文件名长度超过 NAME_MAX,则返回错误信息,并且把 errno 置为 ENAMETOOLONG。
what is the difference between
fopen and open
fread and read
fwrite and write
open and creat
-------------------------------------------
Originally, the open system call could only open files that existed. Now that you can do "open(file, O_CREAT|O_TRUNC|O_WRONLY, mode)", creat no longer has any great use. But lots of code had been written using creat, so it persists. Don't use creat, it's day is long past.
The system calls like read, write, and open must exist if programs are going to be able to use the kernel's drivers. Stuff like fopen, fclose, fread, etc are put of the standard I/O library or stdio. stdio includes other routines like getchar, putchar, etc. So not all of the names start with f. stdio was developed as part of the C language. When C is implemented on other platforms, the stdio library will be there (the ansi C standard mandates this). This is not necessarily true of the unix system calls. So to write C code truely portable to non-unix systems, you must use stdio.
If your program is intended for unix systems only, the most important factor is i/o buffering. If you want to read a file character by character, issuing separate read system calls is slow. A system call is expensive. Even with a disk file, where the data is being fetched from the buffer cache, a separate read for each character will take too long. By using stdio, one read will happen to load some data into the library's buffer. Now if you read character by character, it will go much faster. And that's with a disk file which is using a buffer cache. If you are doing i/o to, say, /dev/tty, there is no buffer cache. Each read and write goes all the way to the driver. On the other hand, if you are reading a disk file block by block, the stdio buffering will probably slow you down. The data is read from the disk into the buffer cache. Then it's copied from the buffer cache into stdio's buffer. Then it's copied from stdio's buffer into your program. So for each application, you need to consider which technique is faster.
Another consideration is that stdio has a richer feature set than is available directly from the system call interface. You can do an ungetc() but there is no unread(). And printf has a ton of features that write() can't do.
原文: