1. 简述同步IO、异步IO、阻塞IO、非阻塞IO之间的联系与区别
1.1 open()函数原型
int open(const char*pathname,int flags);
int open(const char*pathname,int flags,mode_t mode);
1.2 返回值
成功:新打开的文件描述符
失败:-1
open返回的文件描述符一定是最小的而且没有被使用的
1.3 参数
int open(const char*pathname,int flags);
int open(const char*pathname,int flags,mode_t mode);
参数说明:
1.pathname (const char* 类型,表示字符串)
要打开或创建的目标文件
2.flags
打开文件时,可以传入多个参数选项,用下面的
一个或者多个常量进行“或”运算,构成falgs
参数:
O_RDONLY: 只读打开
O_WRONLY: 只写打开
O_RDWR: 读,写打开
这三个常量,必须制定一个且只能指定一个
O_CREAT: 若文件不存在,则创建它,需要使
用mode选项。来指明新文件的访问权限
O_APPEND: 追加写,如果文件已经有内容,这次打开文件所
写的数据附加到文件的末尾而不覆盖原来的内容
1.4 示例
int fd = open("testfiles/test01_01",O_RDWR|O_CREAT,0777);
//创建文件;0777,后三位表示权限,第一位“0”表示8进制。
if (fd==-1) printf("打开文件失败\n");
if (fd > 0) printf("创建文件成功,文件描述符fd=%d\n",fd);
int fd = open("testfiles/test01_01",O_RDWR|O_APPEND);
//打开文件;O_APPEND 副标志O_APPEND,表示在后面写入
if (fd==-1) printf("打开文件失败\n");
if (fd > 0) printf("创建文件成功,文件描述符fd=%d\n",fd);
2.1 write()函数原型
ssize_t write (int fd, const void * buf, size_t count);
2.2 函数返回值
如果顺利write()会返回实际写入的字节数(len)。当有错误发生时则返回-1,错误代码存入errno中。
2.3 函数参数
write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。
2.4 示例
char c_buf[] = "hello world!";//创建字符数组
int w_ret = write(fd,c_buf,12);//向文件里写入12个字节
if(w_ret<0) printf("写入失败\n");
if(w_ret>0) printf("成功写入%d字节\n",w_ret);
3.1 read()函数原型
ssize_t read(int fd, void * buf, size_t count);
3.2 函数返回值
返回值:返回值为实际读取到的字节数, 如果返回0, 表示已到达文件尾或是无可读取的数据。若参数count 为0, 则read()不会有作用并返回0。
3.3 函数参数
文件描述符,read_buf,读出字节数,从文件中读出多少字节到buf中。
3.4 示例
lseek(fd,SEEK_SET,0);//文件描述符指向首部。
char read_buf[50];
int r_ret = read(fd,read_buf,100);
if(r_ret==-1) printf("读入错误\n");
if(r_ret>0) printf("读出%d字节\n",r_ret);
if(r_ret==0) printf("已经读到文件末尾\n");
printf("读出的字符串是:%s\n",read_buf);
//注意,write之后就read不出来了,因为文件描述符已经指向尾部了。
4.1 close()函数原型
int close(int fd)
4.2 close()函数返回值
成功:返回0; 失败:返回-1,并设置errno
4.3 示例
int c_ret = close(fd);
if(c_ret==0) printf("文件fd=%d,关闭成功\n",fd);
if(c_ret==-1) {
printf("文件fd=%d,关闭失败\n",fd);
printf("errno:%d\t%s\n",errno,strerror(errno));
}
5. 代码测试
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
extern bool test01_02();
/* 文件IO */
void test01_01(){
int fd;
bool b_ret = test01_02();//判断"testfiles/test01_01"是否存在。
/* 打开、创建文件 */
if(!b_ret){
fd = open("testfiles/test01_01",O_RDWR|O_CREAT,0777);
//创建文件;0777,后三位表示权限,第一位“0”表示8进制。
if (fd==-1) printf("打开文件失败\n");
if (fd > 0) printf("创建文件成功,文件描述符fd=%d\n",fd);
}else{
fd = open("testfiles/test01_01",O_RDWR|O_APPEND);
//打开文件;O_APPEND 副标志,表示在后面写入
if (fd==-1) printf("打开文件失败\n");
if (fd > 0) printf("打开文件成功,文件描述符fd=%d\n",fd);
}
/* write函数 */
char c_buf[] = "hello world!";//创建字符数组
int w_ret = write(fd,c_buf,12);//向文件里写入12个字节
if(w_ret<0) printf("写入失败\n");
if(w_ret>0) printf("成功写入%d字节\n",w_ret);
/* read函数*/
lseek(fd,SEEK_SET,0);//文件描述符指向首部。
char read_buf[50];
int r_ret = read(fd,read_buf,100);
if(r_ret==-1) printf("读入错误\n");
if(r_ret>0) printf("读出%d字节\n",r_ret);
if(r_ret==0) printf("已经读到文件末尾\n");
printf("读出的字符串是:%s\n",read_buf);
//注意,write之后就read不出来了,因为文件描述符已经指向尾部了。
/* close函数 */
int c_ret = close(fd);
if(c_ret==0) printf("文件fd=%d,关闭成功\n",fd);
if(c_ret==-1) {
printf("文件fd=%d,关闭失败\n",fd);
printf("errno:%d\t%s\n",errno,strerror(errno));
}
}
/* access函数 */
bool test01_02(){
int ret = access("testfiles/test01_01",F_OK);
if(ret==0) {
printf("文件存在\n");
return true;
}
if(ret<0) {
printf("文件不存在\n");
printf("errno: %2d\t%s\n",errno,strerror(errno));
return false;
}
return false;
}