【第5章】文件及IO操作邹昕光哈尔滨工业大学自动化测试与控制研究所2012课程内容嵌入式系统文件访问的需求基本IO操作函数带缓冲的文件IO操作函数高级文件IO操作嵌入式系统文件访问需求配置文件能给嵌入式系统应用带来灵活性;环境参数;常量值;用户偏好;……嵌入式系统采集的数据可以以文件形式存储;数据采集;事件记录;错误导出。……基本IO操作函数openwritereadclose头文件sys/types.hsys/stat.hfcntl.hopenintopen(constchar*filename,intflags,mode_tmode)打开一个文件;【参数】filename:待打开文件的文件名;flags:文件打开的方式;mode:文件访问权限【返回值】如果打开成功,返回文件描述符;如果打开失败,ERROR;openflagsO_RDONLY以只读方式打开;O_WRONLY以只写方式打开;O_RDWR以读写方式打开;O_CREATE如果文件不存在则创建文件;O_APPEND打开后保证文件偏移指针置于文件位,对文件写操作总是在文件后增加内容。对设备不起作用。O_TRUNC如果文件是正规文件,则打开后文件长度变为0,。对设备不起作用。readintread(intfd,char*buffer,size_tmaxbytes)从文件或设备中读取数据;【参数】fd:文件描述符;buffer:指向接收数据缓存的指针;maxbytes:读入缓存的最大数据量【返回值】成功返回实际读取的字节数,小于等于maxbytes;如果读到文件尾返回0;失败返回ERROR;writeintwrite(intfd,char*buffer,size_tnbytes)向文件中写入数据;【参数】fd:文件描述符;buffer:指向待写入数据缓存的指针;nbytes:写入数据的长度【返回值】成功返回写入的字节数(对于正规文件,返回字节数总是等于nbytes),否则出错;失败返回ERROR;closeSTATUSclose(intfd)关闭文件;【参数】fd:文件描述符;【返回值】成功,返回底层驱动函数的状态;失败,返回ERROR;ioctlintioctl(intfd,intfunction,…)指向IO控制功能;【参数】fd:文件描述符;function:功能码;【返回值】成功,返回底层驱动函数的状态;失败,返回ERROR;例子writeFileDemoreadFileDemoioctlDemo带缓冲的文件IO操作函数C-RuntimeLibrary提供一套文件操作函数;使用时需要包含头文件stdio.h常用文件操作函数fopenfclosefputsfgetsfreadfwrite文件操作函数常用文件操作函数(续)fseekfeofferrorperrorfopenFILE*fopen(constchar*filename,constchar*mode)打开一个文件;【参数】filename:待打开文件的文件名;mode:文件打开的方式;【返回值】如果打开成功,返回指向打开文件的指针;如果打开失败,返回值为NULL,并设置全局变量errno为EINVAL;fopen【说明】常用的mode值“r”将文件以读方式打开,如果文件不存在或找不到,调用失败;“w”将文件以写方式打开,如果文件存在,则文件原来的内容被清空;如果文件不存在,则创建文件;“t”以文本文件方式打开;“b”以二进制文件方式打开fopen【示例】FILE*stream1=NULL;FILE*stream2=NULL;stream1=fopen(“textfile.txt”,“wt”);stream2=fopen(binfile.bin,rb);fcloseintfclose(FILE*stream)关闭文件【参数】stream:指向待关闭文件的指针;【返回值】如果成功关闭返回0;如果关闭失败返回EOF。fclose【示例】fclose(stream1);fclose(stream2);fputsintfputs(constchar*str,FILE*stream)将一个字符串写入文件;【参数】str:待写入的字符串;stream:指向打开文件的指针;【返回值】如果成功返回一个非负值;如果失败返回EOF。fputs【示例】fputs(“EmbeddedSystemConfigurations\n”,stream);fgetschar*fgets(char*str,intn,FILE*stream)从文件中读出一个字符串;【参数】str:存储读出的字符串;n:期望读出的最大字符数;stream:指向打开文件的指针;【返回值】成功调用返回str;调用失败或遇到文件尾返回NULL;fgets【说明】fgets试图读入n个字符;fgets停止读取的判断条件为如果遇到换行符;如果读到文件尾;如果读到n-1个字符;在读到的字符串后在添加结束符’\0’。fgets【示例】打印5行配置信息;假定每行配置信息的字符数不超过100字节。charconfig[100];intitemCount=0;while(!feof(stream)){fgets(config,100,stream);if(ferror(stream)){perror(readfailed);break;}if(itemCount=5)printf(config);itemCount++;memset(config,0,100);}freadsize_tfread(void*buffer,size_tsize,size_tcount,FILE*stream)从打开的文件中读取数据;【参数】buffer:指向存储数据的内存位置;size:item的大小,以byte为单位;count:期望读取的item数目;stream:指向打开文件的指针;fread【返回值】返回实际读取item的数量,当操作发生错误或者读到文件末尾时,返回值可能会小于count参数;使用feof区分读写错误和到达文件末尾;【说明】fread一次至多读取count个大小为size字节的items,并把数据存储在buffer中;fwritesize_tfwrite(constvoid*buffer,size_tsize,size_tcount,FILE*stream)向文件中写入数据;【参数】buffer:指向待写入数据的内存位置;size:item的大小,以byte为单位;count:期望写入的item数目;stream:指向打开文件的指针;fwrite【返回值】返回实际写入item的数量,当操作发生错误时,返回值可能会小于count参数;【示例】constchar*binFileHeader=EmbeddedSystemDataCollectionFile;size_tbinFileHeaderSize=strlen(binFileHeader);fwrite(binFileHeader,sizeof(char),binFileHeaderSize,stream);fseekintfseek(FILE*stream,longoffset,intorigin)将文件指针移动到指定位置;【参数】stream:指向打开文件的指针;offset:相对于参数origin的偏移量;origin:初始位置;【返回值】调用成功,返回值为0;否则返回值非0。fseek【说明】offset是相对于origin的偏移位置,可以是正值也可以是负值;origin指定初始位置,可以取以下三种值SEEK_CUR:代表当前位置;SEEK_END:代表文件尾;SEEK_SET:代表文件起始位置;fseek【说明】(续)定位到文件第10个字符后;fseek(stream,10,SEEK_SET)定位到文件尾前10个字符;fseek(stream,-10,SEEK_END)定位到当前位置前10个字符;fseek(stream,-10,SEEK_CUR)fseek【说明】(续)黑洞文件例子;如果当前文件大小为10;调用fseek(stream,1024*1024-1,SEEK_SET);之后调用fwrite(“1”,1,1,stream);该文件大小显示为1M字节;但内容只有11字节。feofintfeof(FILE*stream)判断是否超过文件尾;【参数】stream:指向打开文件的指针【返回值】如果读操作超过文件尾,则返回值为非0;否则,返回值为0;feof【说明】假设有一个文件大小10字节,如果从文件中读取了10字节,此时文件指针到达了文件尾,但是feof返回值是0;只有读操作超过文件尾,比如读取11个字节,feof才会返回非0值,同时只能读到10个字节。feof【示例】while(!feof(stream)){fgets(config,100,stream);if(ferror(stream)){perror(readfailed);break;}printf(config);}ferrorintferror(FILE*stream)测试文件操作是否出错;【参数】stream:指向打开文件的指针;【返回值】如果之前的文件操作没有错误,返回值为0;如果之前的文件操作有错误,返回值非0。perrorvoidperror(constchar*string)打印错误信息;【参数】string:需要输出的信息;【返回值】无【说明】string的内容首先打印出来,接着打印”:”,再接着打印系统出错信息,最后输出换行符;perror【示例】perror(“writeerror”);文本文件操作示例为嵌入式系统软件提供一个配置文件可以增加系统的灵活性;配置文件一般用文本文件存放;内容适合操作人员阅读和修改。ConfigFileDemo二进制文件操作示例为嵌入式系统软件提供文件存储采集的数据和运行状态具有很实际的用处;数据文件一般采用二进制方式存储;访问简单,性能更好。DataFileDemo其他例子黑洞文件例子BlackHoleFileDemo高级文件IO操作访问文件信息异步IOfstatSTATUSfstat(intfd,structstat*pStat)获取文件信息;【参数】fd:文件描述符;pStat:指向存储文件信息结构体的指针【返回值】成功返回OK;失败返回ERROR。fstat例子fstatDemo异步IOstructaiocbaio_readaio_writeaio_errorstructaiocb每个AIO调用都需要一个AIO控制块aiocb作为参数;AIO函数的调用程序需要为aiocb参数分配空间,并且保证AIO操作期间aiocb参数都可用;一个aiocb结构描述一个AIO操作。多个异步IO操作使用同一个aiocb结构是错误的;结构体定义在aio.h中。structaiocbstructsigeventunionsigvalaio_readintaio_read(structaiocb*pAiocb)启动一个异步读操作;【参数】pAiocb:指向相关的AIO控制块的指针;【返回值】成功返回OK;失败返回ERROR。aio_writeintaio_write(structaiocb*pAiocb)启动一个异步写操作;【参数】pAiocb:指向相关的AIO控制块的指针;【返回值】成功返回OK;失败返回ERROR。aio_errorintaio_error(structaiocb*pAiocb)获取异步I/O的错误状态信息;【参数】pAiocb:指向相关的AIO控制块的指针;【返回值】成功返回OK;失败返回ERROR。例子aioReadFromStandardInputDemo()aioReadFromRegularFileDemo()aioWriteToRegularFileDemo()selectintselect(intwidth,fd_set*pReadFds,fd_set*