"); //-->
linux的API遵循了unix中最流行的界面标准—POSIX标准。
Linux文件主要分为4种:普通文件、目录文件、链接文件和设备文件。
通常,一个进程启动时,都会打开3个文件:标准输入(STDIN_FILENO)、标准输出(STDOUT_FILENO)和标准出错(STDERR_FILENO)处理。分别对应的文件描述符为0、1、2.
不带缓存的文件I/O操作
相关函数:open,close,read,write,lseek,fcntl,select
open
打开或者创建文件
int open(const char *pathname,flags,int perms)
pathname:打开文件名
flags:打开方式
perms 打开权限
返回文件描述符
close
关闭一个已经打开的文件
int close(int fd)
fd:文件描述符
read
从文件描述符中读出文件的指定内容
ssize_t read(int fd,void *buf,size_t count)
fd 文件描述符
buf 存放读取数据的缓存
count 读取数据的字节数
返回 成功:读到的字节数
0:已经读到文件尾
-1:出错
write
向打开的文件写数据
ssize_t write(int fd,void *buf, size_t count)
fd 文件描述符
buf 存放要写的数据的缓存
count 写数据的字节数
返回 成功:已写的字节数
-1:出错
lseek
在指定文件中精确定位
off_t lseek(int fd,off_t offset,int whence)
offset: 偏移量
whence:当前位置的基点
fcntl
文件描述符控制函数
int fcntl(int fd,int cmd,struct flock *lock)
cmd: 命令类型
lock: struct flock
{
short l_type; //锁类型
off_t l_start; //上锁开始位置(偏移量)
short l_whence; //基点
off_t l_len; //锁的长度
pid_t l_pid; //
}
select
I/O多路复用监视函数
int select(int numfds,fd_set *readfds,fd_set *writefds,fd_set *exeptfds,struct timeval *timeout)
struct timeval{
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
numfds 需要检查的号码的最高的文件描述符加1
readfds 由select监视的读文件描述符集合
writefds 由select监视的写文件描述符集合
exeptfds 由select监视的异常文件描述符集合
timeout 等待时间
NULL 永久等待
0 测试完即返回
timeval时间
返回 –1表示出错 0表示超时 若成功则返回准备好的文件描述符
FD_ZERO(fd_set *fdset):清空fdset与所有文件描述符的联系。
FD_SET(int fd, fd_set *fdset):建立文件描述符fd与fdset的联系。
FD_CLR(int fd, fd_set *fdset):清除文件描述符fd与fdset的联系。
FD_ISSET(int fd, fd_set *fdset):检查fd_set联系的文件描述符fd是否可读写,>0表示可读写。
Fopen、fdopen、freopen、fread、fwrite、getc、putc…
总结:
注意:open,close,read,write,lseek,fcntl,select以及带级存的fopen等函数的用法。特别注意fcntl及select的用法。Fcntl在本章作用为给文件加锁解锁。Select用来实现多路I/O的复用。
读取锁为共享型锁,可以建立多个
写入锁为互斥型锁,只能建立一个
写入锁跟读取锁不能同时建立
fcntl默认的为建议性锁,顾名思义,如果一个进程为文件建立了一个写入锁,那么另一个进程对此文件写操作时先人为判断一下有没有写入锁,如果没有,则可进行写操作。如果有,则不可进行写操作,需等待对方解锁。个人理解这更是一种双方协商的锁,完全靠自觉性,如果不判断写入锁是否存在而直接对文件写操作也可以写入数据。而强制性锁则为强制性的,一个进程加了强制性锁之后,另一个进程就不可以对文件做相应操作。
串口 阻塞型 非阻塞型
打开->设置->读写
fopen,open
1. fopen 系列是标准的C库函数;open系列是 POSIX 定义的,是UNIX系统里的system call。
也就是说,fopen系列更具有可移植性;而open系列只能用在 POSIX 的操作系统上。
2. 使用fopen 系列函数时要定义一个指代文件的对象,被称为“文件句柄”(file handler),是一个结构体;而open系列使用的是一个被称为“文件描述符” (file descriptor)的int型整数。
3. fopen 系列是级别较高的I/O,读写时使用缓冲;而open系列相对低层,更接近操作系统,读写时没有缓冲。由于能更多地与操作系统打交道,open系列可以访问更改一些fopen系列无法访问的信息,如查看文件的读写权限。这些额外的功能通常因系统而异。
4. 使用fopen系列函数需要"#include <sdtio.h>";使用open系列函数需要"#include <fcntl.h>" ,链接时要之用libc(-lc)
select函数 , I/O多路复用。可以对指定的字符集进行监视。select系统调用是用来让我们的程序监视多个文件句柄(file descriptor)的状态变化的。
例:如果我们要检测用户是否按了键盘进行输入,我们就应该把标准输入0这个句柄放到select里来检测,如下:
FD_ZERO(&rdfds);
FD_SET(0, &rdfds);
tv.tv_sec = 1;
tv.tv_usec = 0;
ret = select(1, &rdfds, NULL, NULL, &tv); /* 注意是最大值还要加1 */
if(ret < 0) perror("select");/* 出错 */
else if(ret == 0) printf("超时\n"); /* 在我们设定的时间tv内,用户没有按键盘 */
else { /* 用户有按键盘,要读取用户的输入 */
scanf("%s", buf);
}
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。