




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
5.1文件I/O介绍可用的文件I/O函数——打开文件、读文件、写文件等等。大多数linux文件I/O只需用到5个函数:open、read、write、lseek
以及close。 不带缓存指的是每个read和write都调用内核中的一个系统调用。这些不带缓存的I/O函数不是ANSIC的组成部分,但是POSIX组成部分。5.2文件描述符对于内核而言,所有打开文件都由文件描述符引用。当打开一个现存文件或创建一个新文件时,内核向进程返回一个文件描述符。当读、写一个文件时,用open或creat返回的文件描述符标识该文件,将其作为参数传送给read或write。文件描述符是一个非负整数。文件描述符的范围是0~OPEN_MAX。其中0、1、2分别被代换为符号常量,系统留用:STDIN_FILENO0标准输入(默认为键盘)STDOUT_FILENO1标准输出(默认为屏幕)STDERR_FILENO2标准错误输出(默认为屏幕)
注:早期的UNIX版本采用的上限值是19(允许每个进程打开20个文件),对于现在的很多系统其值有变化。5.3基本APIopen函数creat函数read函数write函数close函数lseek函数fcntl函数ioctl函数select实现I/O复用5.3.1基本API——open函数#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>int
open(constchar*pathname,int
oflag, …/*,mode_tmode*/);功能:打开文件返回:若成功为文件描述符,若出错为-1参数:参数名功能说明取值pathname要打开或创建的文件的名字oflag说明对文件的操作方式由<fcntl.h>头文件中的常数定义构成参见下面的取值表mode新建文件的权限设置仅当创建新文件时才使用该参数八进制表示的权限值O_RDONLY只读打开。O_WRONLY只写打开。O_RDWR读、写打开。O_APPEND追加方式写O_CREAT文件不存在时创建O_EXCL结合O_CREAT使用。如果文件存在,返回错误;如果文件不存在,则创建文件O_TRUNC如果此文件存在,而且为只读或只写成功打开,则将其长度截短为0。O_NOCTTY如果pathname指的是终端设备,则不将此设备分配作为此进程的控制终端。O_NONBLOCK如果pathname指的是一个FIFO、一个块特殊文件或一个字符特殊文件,则此选择项为此文件的本次打开操作和后续的I/O操作设置非阻塞方式O_SYNC使每次write都等到物理I/O操作完成。1、Oflag的设置#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<stdio.h>int
main(int
argc,char*argv[]){
int
fd;
fd=open(“./aa.c”,O_TRUNC);
if(fd==-1) {
perror(“fail\n”);
} else {
perror("success\n");
close(fd); } return0;}实例:清空文件(删除文件的全部内容)__即将文件的长度截短为0即O_TRUNC源代码/*文件aa.c不存在,open出错,返回-1。成功执行后,aa.c文件中的内容将被清除*//*perror(char*msg)完成输出msg,并输出perror的执行情况,格式为“msg内容:执行结果提示”*/open("./aa.c",O_TRUNC);open("./aa.c",O_RDWR|O_CREAT,0666);open("./aa.c",O_RDWR|O_TRUNC);open("./aa.c",O_RDWR|O_APPEND);open("./aa.c",O_RDWR|O_CREAT|O_EXCL);open("./aa.c",O_RDWR|O_CREAT|O_EXCL,0666);
demo1demo2实例:分析并使用代码测试以下open函数的功能注意:Oflag的多个值间使用“|”分开Open函数中使用八进制指定ugo的权限2、mode的设置参考文件权限设置命令注意:mode在open中使用八进制,以数字“0”开头【补充】命令“mkdir-m权限文件或路径”与“chmod
权限文件或路径”权限mode
的设置
格式一:[ugoa][+-=][rwx][,...] 格式二:mode可以是数字字符串其中
u
表示该档案的拥有者g
表示与该档案的拥有者属于同一个群体(group)者o
表示其他以外的人a
表示这三者皆是
+
表示增加权限-
表示取消权限=
表示唯一设定权限
r
表示可读取,对应8进制值为4w
表示可写入,对应8进制值为2x
表示可执行,对应8进制值为1例题:采用格式一和格式二等同mkdir-m
a=rwx
file和mkdir-m0777
file
效果相同mkdir-m
ug=rwx,o=x
file
和mkdir-m
0771
file
效果相同
例题:使用“chmod
权限文件或路径”改变文件或路径的权限注意:上面的mkdir和chmod命令中的mode可以使用八进制(如0777)5.3.2基本API——creat函数#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>int
creat(constchar*pathname,mode_t
mode);功能:创建一个新文件。返回:若成功,返回只写方式打开的文件描述符,若出错返回-1。注意:(1)此函数等效于:open(pathname,O_WRONLY|O_CREAT|O_TRUNC, mode);见例:demo3.c5.3.3基本API——read函数#include<unistd.h>ssize_t
read(int
fd,void*buff,size_t
nbytes);功能:从打开文件中读数据返回:read成功,则返回读到的字节数。如已到达文件的尾端,则返回0。若出错为-1。参数:参数名功能说明取值fd被读取文件的文件描述open或creat的返回值buff读取到的数据在内存中的位置一般为字符数组名nbytes期望本次读到的最大长度字符数一般为字符数组的长度注意:(1)读操作从文件的当前位移量处开始,在成功返回之前,该位移量增加实际读得的字节数。(2)有多种情况可使实际读到的字节数少于要求读字节数:读普通文件时,在读到要求字节数之前已到达了文件尾端。例如,若在到达文件尾端之前还有30个字节,而要求读100个字节,则read返回30,下一次再调用read时,它将返回0(文件尾端)。
当从终端设备读时,通常一次最多读一行。
某些面向记录的设备,例如磁带,一次最多返回一个记录。
当从网络读时,网络中的缓冲机制可能造成返回值小于所要求读的字节数。使用规范:charrc[100];intnum=0;int
df=open(文件,读权限);if(df!=-1){ num=read(df,rc,100);
while(num>0) { dosomething;num=read(df,rc,100); }
close(df);}见例:demo4.c补充内容:判断文件的存在性及权限补充:判读文件的存在性及权限#include<unistd.h>
#include<fcntl.h>
int
access(constchar*pathname,intmode);
功能:检查调用进程是否可以对指定的文件执行某种操作。
参数:pathname:需要测试的文件路径名。
mode:需要测试的操作模式,可能值是一个或多个(组合体):R_OK(可读?)W_OK(可写?)X_OK(可执行?)F_OK(文件存在?)返回:成功执行时,返回0。失败返回-1
见例:
demo5.c5.3.4基本API——write函数#include<unistd.h>ssize_t
write(int
fd,constvoid*buff,size_t
nbytes);功能:向打开文件写数据返回:若成功为已写的字节数,若出错为-1。注意:(1)其返回值通常与参数nbytes的值相同,否则表示出错。write出错的一个常见原因是:磁盘已写满。超过了对一个给定进程的文件长度限制。(2)对于普通文件,写操作从文件的当前位移量处开始。如果在打开该文件时,指定了O_APPEND选择项,则在每次写操作之前,将文件位移量设置在文件的当前结尾处。在一次成功写之后,该文件位移量增加实际写的字节数。使用规范(一次性输出字符串到文件):charrc[100]=字符串;//设字符串的最大长度为100intnum=0,TotalLong=strlen(rc);int
df=open(文件,写权限);if(df!=-1){ //一次性输出
if(num!=TotalLong) {
printf(“输出错误!”); return0; } else {
printf(“成功输出!”); }}见例:um=write(df,rc,TotalLong);使用规范(分次输出字符串到文件):charrc[3000]=“…”;//设字符串的最大长度为3000char*prc=rc;intnum=0,TotalLong=strlen(rc);int
df=open(文件,写权限);if(df!=-1){//每次希望输出100个字符
while(num!=TotalLong) {
//修正偏移量
num=write(df,prc,100);
TotalLong=TotalLong-num; }}见例:demo7.c文件复制见例:um=write(df,prc,100);prc=prc+num;
//不能使用prc+100,由于num<=1005.3.5基本API——close函数#include<unistd.h>intclose(int
filedes);功能:关闭一个打开文件返回:若成功为0,若出错为-1注意:当一个进程终止时,它所有的打开文件都由内核自动关闭。作为一个习惯好的程序员,应该显式地用close关闭打开的文件。5.3.6基本API——lseek函数1、当前文件偏移量当前文件偏移量是一个非负整数,用以度量打开文件从文件开始处计算的字节数。通常,读、写操作都从当前文件偏移量处开始,并使偏移量增加所读或写的字节数。按系统默认,当打开一个文件时,除非指定O_APPEND选择项,否则该位移量被设置为0。可以调用lseek显式地定位一个打开文件的文件偏移量。2、lseek#include<sys/types.h>#include<unistd.h>off_t
lseek(int
fd,off_toffset,intwhence);功能:显式地定位一个打开文件的文件偏移量。返回:若成功为新的文件位移,若出错为-1。参数:参数名功能说明取值fd被读取文件的文件描述open或creat的返回值offset相对偏移量偏移量的值,可以有正负whence相对参考方式SEEK_SET:位移量=文件开始处+offset个字节SEEK_CUR:位移量=当前位移量+offset个字节SEEK_END:位移量=文件长度+offset个字节见例注释:demo9_1.c见例:demo9.c补充STDOUT_FILENO补充:标准输入,标准输出,标准出错1、unix系统调用中的标准输入,标准输出,标准出错有两组:STDOUT_FILENOSTDIN_FILENOSTDERR_FILENOstdin
stdout
stderr
2、相同点:STDOUT_FILENOSTDIN_FILENOSTDERR_FILENO和stdin
stdout
stderr
他们表示的意思是差不多的,都是unix系统调用中的标准输入,标准输出,标准出错。补充:标准输入,标准输出,标准出错3、区别:他们的类型是不一样stdin等是FILE*类型,属于标准I/O,在<stdio.h>。#include<stdio.h>externFILE*stdin;externFILE*stdout;externFILE*stderr;STDIN_FILENO等是文件描述符,是非负整数,一般定义为0,1,2,属于没有buffer的I/O,直接调用系统调用,在<unistd.h>。在/usr/include/unistd.h中有如下定义:/*Standardfiledescriptors.*/#defineSTDIN_FILENO0/*Standardinput.*/#defineSTDOUT_FILENO1/*Standardoutput.*/#defineSTDERR_FILENO2/*Standarderroroutput.*/例题:#include<unistd.h>int
main(void){
intn;charbuf[100];
while(n=read(STDIN_FILENO,buf,100))//读取标准输入到buf中,返回读取字节数。{
if(n!=write(STDOUT_FILENO,buf,n))//把buf
写到标准输出中
perror("writeerror");}
if(n<0)perror("readerror");return0;}1、标准终端运行结果:输入一行,马上输出一行,也就是按照原样输出注意:终端输入文件时,使用ctrl+d来输入文件结束符demo10.c2、使用输出重定向来运行可以使得输入的字符串并不是输出到终端,而是输出到指定的文件中3、使用输入输出重定向来运行输入的字符串可以不从键盘,而是从文件或已有的文件描述符中获得分析wc命令,更多关于重定向命令参照”重定向”5.3.7基本API——fcntl函数#include<sys/types.h>#include<unistd.h>#include<fcntl.h>int
fcntl(int
fd,int
cmd);
int
fcntl(int
fd,int
cmd,longarg);
int
fcntl(int
fd,int
cmd,structflock*lock);功能:根据文件描述符来操作文件的特性
。参数:参数名说明取值fd被操作的文件描述符cmd操作命令F_DUPFD复制一个现有的描述符F_GETFD或F_SETFD获得/设置文件描述符标记
F_GETFL或F_SETFL获得/设置文件状态标记
F_GETOWN或F_SETOWN获得/设置异步I/O所有权
F_GETLK,F_SETLK或F_SETLKW获得/设置记录锁注意:F_SETFL将文件状态标志设置为第三个参数的值(取为整型值)。可以更改的几个标志是:O_APPEND,O_NONBLOCK,O_SYNC,O_ASYNC。F_GETOWN取当前接收SIGIO和SIGURG信号的进程ID或进程组ID。F_SETOWN设置接收SIGIO和SIGURG信号的进程ID或进程组ID。正的arg指定一个进程ID,负的arg表示等于arg绝对值的一个进程组ID。F_SETLKW是F_SETLK的阻塞版本(命令名中的W表示等待wait)。如果存在其他锁,则调用进程睡眠;如果捕捉到信号则睡眠中断
返回值:如果出错,所有命令都返回-1,如果成功则返回某个其他值(返回值与命令cmd有关)。
int
main(void){
int
fd,flag; if((fd=open("./test.txt",O_RDWR|O_APPEND|O_CREAT|O_TRUNC,0666))<0) {
perror("open"); exit(-1); }
write(fd,"yang",4);
lseek(fd,0,SEEK_SET);
write(fd,"zhu",3); return0;}
例题:获得并修改文件状态标记。代码:demo11flag=fcntl(fd,F_GETFL);flag=flag&~O_APPENDfcntl(fd,F_SETFL,flag);int
fcntl(int
fd,int
cmd,structflock*lock);1、文件锁的使用环境:在文件已经共享的情况下,也就是当多个用户共同使用,操作一个文件的情况,这时LINUX通常采用的方法是给文件上锁,来避免共享的资源产生竞争的状态。补充:用fcntl给文件加锁flock结构体包含了设置记录锁的具体状态成员flock的结构如下所示:Structflock{shortl_type; /*锁的类型,取值如下: F_RDLCK读取锁(共享锁)F_WRLCK写入锁(排斥锁)F_UNLCK解锁*/off_t
l_start; //相对位移量(字节)shortl_whence; /*相对位移量的起点,取值如下:SEEK_SET/SEEK_CUR/SEEK_END(同lseek的whence)*/off_t
l_len;//加锁区域的长度pid_t
l_pid;}2、flock结构注意:为加锁整个文件,通常的方法是将l_start
说明为0,l_whence
说明为SEEK_SET,l_len
说明为0。例题:写入锁为互斥锁,一个时刻只能有一个写入锁存在。代码:demo12_1例题:读取锁为共享锁,当一个进程已设定读取锁后,另一个进程还可以设置读取锁。代码:demo12_25.3.8基本API——ioctl函数#include<unistd.h>#include<sys/ioctl.h>int
ioctl(int
fd,int
cmd,...);功能:ioctl最主要使用在终端设备I/O控制。返回:若出错则为-1,若成功则为其他值。参数:参数名说明取值fd要控制的设备文件描述符cmd要设备完成的操作cmd参数cmd操作的参数代码:demo13#include<sys/types.h>#include<sys/time.h>#include<unistd.h>intselect(int
maxfd,
fd_set*readset, fd_set*writeset,
fd_set*exceptset, conststructtimeval*timeout);功能:同时监控多个文件描述符上是否有输入、输出、错误。返回:准备就绪的描述符数,若超时则为0,若出错则为-1。5.3.9基本API——
select函数参数名说明取值maxfd要被监控的描述符个数最大fd+1readset被监控的是否有输入的文件描述符集初始化时,被监控描述字的相应位置0;调用select后,未就就绪设备的相应位被置为0,就绪位置为1writeset被监控的是否有输出的文件描述符集exceptset被监控的是否有错误产生的文件描述符集timeval监控的超时时间structtimeval类型的指针。参见timeval取值参见文件描述符集操作宏函数代码:demo17select函数根据希望进行的文件操作对文件描述符进行分类处理,对文件描述符的处理主要设计4个宏函数:FD_ZERO(fd_set*set) 清除一个文件描述符集;FD_SET(int
fd,fd_set*set) 将一个文件描述符加入文件描述符集中;FD_CLR(int
fd,fd_set*set)
将一个文件描述符从文件描述符集中清除;FD_ISSET(int
fd,fd_set*set)
测试该集中的一个给定位是否有变化;文件描述符集操作宏函数参数名说明取值maxfd要被监控的描述符个数最大fd+1readset被监控的是否有输入的文件描述符集初始化时,被监控描述字的相应位置0;调用select后,未就就绪设备的相应位被置为0,就绪位置为1writeset被监控的是否有输出的文件描述符集exceptset被监控的是否有错误产生的文件描述符集timeval监控的超时时间structtimeval类型的指针。参见timeval取值参见文件描述符集操作宏函数代码:demo17timeval取值NULL:永远等待,直到捕捉到信号或文件描述符已准备好为止;具体值:
structtimeval类型的指针,若等待为timeout时间还没有文件描述符准备好,就立即返回;0:从不等待,测试所有指定的描述符并立即返回;structtimeval{longtv_sec;/*seconds*/longtv_usec;/*microseconds*/};timeval结构体代码:demo14#include<sys/time.h>int
gettimeofday(struct
timeva
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 游泳救生员在泳场管理中的角色及试题及答案
- 2024年种子繁育员的管理战略试题及答案
- 2024年裁判员考核题目及答案
- 2024年农业植保员考试前的最后冲刺试题及答案
- 模具设计师资格考试快速学习试题及答案
- 工作中的压力管理策略计划
- bim装修施工方案
- 游泳救生员个人卫生管理试题及答案
- 熟悉2024年体育经纪人试题及答案
- 环保措施在企业运营中的实施计划
- 可燃气体报警仪检验记录
- 自动控制原理全套ppt课件(完整版)
- 手卫生相关知识考核试题与答案
- 《同分母分数加减法》教学课件人教新课标
- 产业经济学第三版(苏东水)课后习题及答案完整版
- 初中综合实践课程标准
- 首件检验记录表(标准样版)
- 中建六局建设发展公司责任目标管理考核办法
- 太阳能光伏发电系统PVsyst运用
- 压实沥青混合料密度(表干法)自动计算
- 博硕BSL2236OAC全自动说明书(触摸屏)
评论
0/150
提交评论