原创 文件 I/O编程

2009-5-22 09:56 3140 12 12 分类: MCU/ 嵌入式

linuxAPI遵循了unix中最流行的界面标准POSIX标准


 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


Linux文件主要分为4种:普通文件、目录文件、链接文件和设备文件


 


通常,一个进程启动时,都会打开3个文件:标准输入(STDIN_FILENO)、标准输出(STDOUT_FILENO)和标准出错(STDERR_FILENO)处理。分别对应的文件描述符为012.


不带缓存的文件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):建立文件描述符fdfdset的联系。


FD_CLR(int fd, fd_set *fdset):清除文件描述符fdfdset的联系。


FD_ISSET(int fd, fd_set *fdset):检查fd_set联系的文件描述符fd是否可读写,>0表示可读写。


 


Fopenfdopenfreopenfreadfwritegetcputc…


 


 



 


总结:


注意:open,close,read,write,lseek,fcntl,select以及带级存的fopen等函数的用法。特别注意fcntlselect的用法。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);
}  

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
12
关闭 站长推荐上一条 /3 下一条