zoukankan      html  css  js  c++  java
  • I/O -x open()-read()-write()-close()-lseek()

      大多数unix文件I/O只需要用到5个函数:open,read,write,lseek,close。这些函数都为不带缓存的I/O,不带缓存指的是每个read和write都调用内核中的一个系统调用。这些函数使用时要用到三个头文件:sys/types.h,sys/stat.h,fcntl.h

    open函数:int open(const char path *name, int oflag,...);
      返回:若成功为只写打开的文件描述符,若错误为-1。
    调用open函数可以打开或创建一个文件,仅当创建新文件时才使用第三个参数,由open函数返回的文件描述符一定是最小的未用的描述符数字。
      第一个参数为路径名
      第二个参数为文件状态标志:
    O_RDONLY或0:可读
    O_WRONLY或1:可写
    O_RDWR或2:可执行
    O_APPEND:每次写时都加到文件的尾部
    O_CREAT:若此文件不存在则创建它,使用此选项时,需同时说明第三个参数mode,用其说明该新文件的存取许可权位
    O_EXCL:如果同时指定了O_CREAT,而文件已经存在,则出错,这可测试一个文件是否存在,如果不存在则创建此文件成为一个原子操作
    O_TRUNC:如果此文件存在,而且为只读或只写成功打开,则将其长度截短为0
    O_NOCTTY:如果pathname指的是终端设备,则不将此设备分配作为此进程的控制终端
    O_NONBLOCK:如果pathname指的是一个FIFO,一个块特殊文件或一个字符特殊文件,则此选择项为此文件的本次打开操作和后续的I/O操作设置非阻塞方式
    O_SYNC:使每次write都等到物理I/O操作完成
      第三个参数一般为文件权限:
    S_IRWXU,0700:代表该文件所有者具有可读,可写,可指向的权限
    S_IRUSR或S_IREAD,0400:代表该文件所有者具有可读取的权限
    S_IWUSR或S_IWRITE,0200:代表该文件所有者具有可写入的权限
    S_IXUSR或S_IEXEC,0100:代表该文件所有者具有可指向的权限
    S_IRWXG,0070:代表该文件用户组具有可读,可写,可执行的权限
    S_IRGRP,0040:代表该文件用户组具有可读的权限
    S_IWGRP,0020:代表该文件用户组具有可写的权限
    S_IXGRP,0010:代表该文件用户组具有可执行的权限
    S_IRWXO,0007:代表其他用户具有可读,可写,可执行的权限
    S_IROTH,0004:代表其他用户具有可读的权限
    S_IWOTH,0002:代表其他用户具有可写的权限
    S_IXOTH,0001:代表其他用户具有可执行的权限

    creat函数:int creat(const char *pathname, mode_t mode);
      返回:若成功为只写打开的文件描述符,若出错为-1
      该函数等效于:open(pathname,O_WRONLY|O_CREAT|O_TRUNC,mode);
      用于创建一个新文件

    read函数 :ssize_t read (int fd, void *buf, size_t count);
    返回值
    成功返回读取的字节数,出错返回-1并设置errno,如果在调read之前已到达文件末尾,则这次read返回0。
    参数
    参数count是请求读取的字节数,读上来的数据保存在缓冲区buf中,同时文件的当前读写位置向后移。


    注意这个读写位置和使用C标准I/O库时的读写位置有可能不同,这个读写位置是记在内核中的,而使用C标准I/O库时的读写位置是用户空间I/O缓冲区中的位置。
    比如用fgetc读一个字节,fgetc有可能从内核中预读1024个字节到I/O缓冲区中,再返回第一个字节,这时该文件在内核中记录的读写位置是1024,而在FILE结构体中记录的读写位置是1。注意返回值类型是ssize_t,表示有符号的size_t,这样既可以返回正的字节数、0(表示到达文件末尾)也可以返回负值-1(表示出错)。
    read函数返回时,返回值说明了buf中前多少个字节是刚读上来的。有些情况下,实际读到的字节数(返回值)会小于请求读的字节数count,例如:读常规文件时,在读到count个字节之前已到达文件末尾。例如,距文件末尾还有30个字节而请求读100个字节,则read返回30,下次read将返回0。

     1 #include <stdio.h>
     2 #include <io.h>
     3 #include <alloc.h>
     4 #include <fcntl.h>
     5 #include <process.h>
     6 #include <sysstat.h>
     7 int main(void)
     8 {
     9 void* buf ;
    10 int handle;
    11 int bytes ;
    12 buf=malloc(10);
    13 /*
    14 LooksforafileinthecurrentdirectorynamedTEST.$$$andattempts
    15 toread10bytesfromit.Tousethisexampleyoushouldcreatethe
    16 fileTEST.$$$
    17 */
    18 handle=open("TEST.$$$",O_RDONLY|O_BINARY,S_IWRITE|S_IREAD);
    19 if(handle==-1)
    20 {
    21 printf("ErrorOpeningFile
    ");
    22 exit(1);
    23 }
    24 bytes=read(handle,buf,10);
    25 if(bytes==-1)
    26 {
    27 printf("ReadFailed.
    ");
    28 exit(1);
    29 }
    30 else 
    31 {
    32 printf("Read:%dbytesread.
    ",bytes);
    33 }
    34 return0 ;
    35 }

    write(将数据写入已打开的文件内)
    表头文件
    #include<unistd.h>
    定义函数
    ssize_t write (int fd,const void * buf,size_t count);
    函数说明
    write()会把指针buf所指的内存写入count个字节到参数fd所指的文件内。当然,文件读写位置也会随之移动。
    返回值
    如果顺利write()会返回实际写入的字节数。当有错误发生时则返回-1,错误代码存入errno中。
    错误代码
    EINTR 此调用被信号所中断。
    EAGAIN 当使用不可阻断I/O 时(O_NONBLOCK),若无数据可读取则返回此值。
    EBADF 参数fd非有效的文件描述词,或该文件已关闭。

    函数名: write
    功 能: 写到一文件中
    用 法: int write(int handle, void *buf, int nbyte);
    程序例:

     1 #include<stdlib.h>
     2 #include<unistd.h>
     3 #include<stdio.h>
     4 #include<string.h>
     5 #include<fcntl.h>
     6 #include<errno.h>
     7 intmain(void)
     8 {
     9 inthandle;
    10 charstring[40];
    11 intlength,res;
    12 /*
    13 Createafilenamed"TEST.$$$"inthecurrentdirectoryandwrite
    14 astringtoit.If"TEST.$$$"alreadyexists,itwillbeoverwritten.
    15 */
    16 if((handle=open("TEST.$$$",O_WRONLY|O_CREAT|O_TRUNC,
    17 S_IREAD|S_IWRITE))==-1)
    18 {
    19 printf("Erroropeningfile.
    ");
    20 exit(1);
    21 }
    22 
    23 strcpy(string,"Hello,world!
    ");
    24 length=strlen(string);
    25 
    26 if((res=write(handle,string,length))!=length)
    27 {
    28 printf("Errorwritingtothefile.
    ");
    29 exit(1);
    30 }
    31 
    32 printf("Wrote%dbytestothefile.
    ",res);
    33 close(handle);
    34 return0;
    35 }
    1 structxfcb{
    2 charxfcb_flag;/*Contains0xfftoindicatexfcb*/
    3 charxfcb_resv[5];/*ReservedforDOS*/
    4 charxfcb_attr;/*Searchattribute*/
    5 structfcbxfcb_fcb;/*Thestandardfcb*/
    6 };

    名称 : write
    使用权限 : 所有使用者
    使用方式 :
    write user [ttyname]
    说明 : 传讯息给其他使用者
    user : 预备传讯息的使用者帐号
    ttyname : 如果使用者同时有两个以上的 tty 连线,可以自行选择合适的 tty 传讯息
    例子.1 :
    传讯息给 Rollaend,此时 Rollaend 只有一个连线 :
    write Rollaend
    接下来就是将讯息打上去,结束请按 ctrl+c
    例子.2 :传讯息给 Rollaend,Rollaend 的连线有 pts/2,pts/3 :
    write Rollaend pts/2
    接下来就是将讯息打上去,结束请按 ctrl+c
    注意 : 若对方设定 mesg n,则此时讯息将无法传给对方

    close函数:int close(int filedes);
      返回:若成功为0,若出错为-1
      关闭一个文件时也释放该进程加在该文件上的所有记录锁,当一个进程终止时,它所有的打开文件都由内核自动关闭。

    lseek函数:off_t lseek(int filedes, off_t offset, int whence);
      返回:若成功为新的文件位移,若出错为-1
      每个打开文件都有一个与其相关联的”当前文件位移量”,它是一个非负整数,用以度量从文件开始处计算的字节数。按系统默认,当打开一个文件时,除非指定O_APPEND选项时,否则该位移量被设置为0。通常读,写操作都从当前文件位移量处开始,并使位移量增加所读或写的字节数。可以调用lseek显式地定位一个打开的文件。
      对参数offset的解释与参数whence的值有关。
        若whence是SEEK_SET,则将该文件的位移量设置为距文件开始处offset个字节
        若whence是SEEK_CUR,则将该文件的位移量设置为其当前值加offset,offset可为正或负
        若whence是SEEK_END,则将该文件的位移量设置为文件长度加offset,offset可为正或负
    早期用0,1,2代铁SEEK_SET,SEEK_CUR,SEEK_END。
    某些设备也可能允许负的位移量,但对于普通文件,则其位移量必须是非负值
    范例:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <sys/types.h>
     4 #include <sys/stat.h>
     5 #include <fcntl.h>
     6 int main(void)
     7 {
     8 int fd, size;
     9 char buf1[]="Hello, world";
    10 char buf2[50];
    11 if((fd=open("/home/sam/helloworld",O_CREAT|O_TRUNC|O_RDWR,0666))==-1)
    12 {
    13 printf("Open or create file named "helloworld" failed.
    ");
    14 exit(1);
    15 }
    16 write(fd,buf1,sizeof(buf1));
    17 close(fd);
    18 if((fd=open("/home/sam/helloworld",O_RDONLY))==-1)
    19 {
    20 printf("Open file named "helloworld" failed.
    ");
    21 exit(1);
    22 }
    23 size=read(fd,buf2,sizeof(buf2));
    24 close(fd);
    25 printf("%s
    ",buf2);
    26 if((fd=open("/home/sam/helloworld",O_RDONLY))==-1)
    27 {
    28 printf("Open file named "helloworld" failed.
    ");
    29 exit(1);
    30 }
    31 lseek(fd,6,SEEK_SET);
    32 size=read(fd,buf2,sizeof(buf2));
    33 printf("%s
    ",buf2);
    34 close(fd);
    35 return 0;
    36 }

    相关函数
    fcntl,lseek,sync,fsync,fwrite

  • 相关阅读:
    ASP.NET使用UEditor入门与常见问题
    关于发布者策略程序集学习记录
    Myeclipse 10安装,以及Flex4插件(原)
    IE、Chrome等浏览器实现PDF预览(原)
    Oracle数据库中文显示乱码的最简单解决办法
    关于程序集的结构(2)C#和.NET2.0实战学习笔记
    关于AppDomain
    关于强名称程序集 C#和.NET2.0实战学习记录
    数据库查询·聚合分支格式化日期·思维导图&要点&误点(含示例)
    如何在SERVER2003上安装MySQL?(附安装教程及资源地址)
  • 原文地址:https://www.cnblogs.com/pencil-zh/p/4507702.html
Copyright © 2011-2022 走看看