《UNIX环境高级编程》学习笔记二 —— 文件IO

10 篇文章 0 订阅

         本章描述的函数被称为不带缓冲的IO,这些不带缓冲的IO函数不是ISO C标准的组成部分。但是,它们是POSIX.1和Single UNIX Specification的组成部分。

1.文件描述符

        按照惯例,UNIX系统shell把文件描述符0与进程的标准输入关联;文件描述符1与标准输出关联;文件描述符2与标准错误关联。0,1,2通常替换成符号常量STDIN_FILENO,STDOUT_FILENO,STDERR_FILENO。

 

2.函数open

        调用open函数可以打开或创建一个文件。

        #include <fcntl.h>

        int open(const char *path, int oflag, ...);

       

        最后参数写为...是因为ISO C用这种方法表明余下参数数量及其类型是可变的。对于open函数而言,仅当创建新文件时才使用最后参数。

       path参数是要打开或创建文件的名字;oflag参数可用来说明此函数的多个选项。用下列一个或多个常量进行“或”运算构成oflag参数。

        O_RDONLY           只读打开

        O_WRONLY          只写打开

        O_RDWR               读写打开

        O_APPEND           每次写时都追加到文件尾端

        O_CREAT              若此文件不存在则创建它

        O_TRUNC             将文件长度截断为0(类似将文件清空重写)

        函数若成功,返回文件描述符;否则,返回-1。 

 

3.函数close

        调用close函数关闭一个打开文件。

        #include  <unistd.h>

        int close(int fd);

 

        参数fd为文件描述符;

        函数若成功,返回0;否则,返回-1; 

        关闭一个文件时还会释放该进程加在该文件上的所有记录锁,之后会讨论这一点。

        当一个进程终止时,内核自动关闭它所有的打开文件。很多程序都利用这一点而不显式地用close关闭文件。

       

4.函数lseek

        每个打开文件都有一个与其相关联的“当前文件偏移量”,通常是一个非负整数,用以度量从文件开始处计算的字节数。

        通常,读、写操作都从当前文件偏移量处开始,并使偏移量增加所读写的字节数。按默认情况,当打开一个文件时,除非指定O_APPEND选项,否则偏移量被设置为0。

         调用lseek函数可以为一个打开文件设置偏移量。该偏移量用于下一次读写操作。

         #include  <unistd.h>

         off_t  lseek(int  fd,  off_t   offset,   int  whence);

 

         参数offset和参数whence有关:

         当whence是SEEK_SET,则将文件的偏移量设置为据文件开始处offset个字节;

         当whence是SEEK_CUR,则将文件的偏移量设置为其当前值加offset,offset可正可负;

         当whence是SEEK_END,则将文件的偏移量设置为文件长度加offset,offset可正可负。

         若函数成功,返回新的文件偏移量;否则,返回-1。

 

        lseek函数可以实现文件内容拓展(当offset大于0,whence为SEEK_END时),但需要在使用函数后要再进行一次写操作(无论写入多大的数)

 

5.函数read

        #include  <unistd.h>

        ssize_t  read(int  fd,  void  *buf,  size_t  nbytes);

 

        读操作从文件的当前偏移量处开始,在成功返回之前,该偏移量将增加实际读到的字节数。       

        函数成功,返回读到的字节数,若已到文件尾,返回0;否则,返回-1;  

 

        注意:多种情况可能使实际字节数少于要求字节数:

      (1)文件内字节数小于要求读的字节数;

      (2)从终端设备读时,通常一次最多读一行(后面会讲如何改变);

      (3)从网络读时,网络缓冲机制可能造成返回值小于要求读字节数;

 

6.函数write

        #include  <unistd.h>

        ssize_t  write(int  fd,  const  void  *buf,  size_t  nbytes);

 

        函数成功,返回已写字节数;否则,返回-1。  

 

        注意:对UNIX系统而言,文本文件与二进制文件并无区别,所以程序对两种文件都有效。

 

7.文件共享

        每个进程在进程表中都有一个记录项,记录项中包含一张文件描述符表,其中包含:

        1.1 文件描述符标志

        1.2 指向一个文件表项的指针

        基于1.2,文件表项包含:

        2.1 文件状态标志(读、写、同步、非阻塞)

        2.2 当前文件偏移量

        2.3 指向该文件V节点表项的指针

        基于2.3,V节点表项包含:

        3.1 文件类型

        3.2 对此文件进行操作函数的指针

        3.3 对于大多数文件,还有I节点

        基于3.3,I节点包含

        4.1 文件的所有者、文件长度、指向文件实际数据块在磁盘上所在位置的指针

 

        当两个进程打开了同一文件时,指向V节点表项的指针相同。

 

8.原子操作

        任何要求多于一个函数调用的操作都不是原子操作,因为在两个函数调用之间,内核有可能临时挂起进程,引发错误。

 

9.函数dup和dup2

        #include  <unistd.h>

        int dup(int fd);

        int  dup2(int  fd,  int  fd2);

       有dup返回的新文件描述符一定是当前可用文件描述符中的最小值。对于dup2,可以用fd2参数指定新描述符的值。如果fd2已经打开,则先将其关闭。

 

        该函数可以对已存在的文件描述符创建一个引用。

        函数成功返回新的文件描述符;函数失败,返回-1。

 

10.函数fcntl

         #include  <fcntl.h>

         int  fcntl(int  fd,  int  cmd...);

         fcntl函数有以下5中功能:

       (1)复制一个已有的描述符(cmd = F_DUPFD或F_DUPFD_CLOEXEC)

       (2)获取/设置文件描述符标志(cmd = F_GETFD或F_SETFD)

       (3)获取/设置文件状态标志(cmd = F_GETFL或F_SETFL)

       (4)获取/设置异步I/O所有权(cmd = F_GETOWN或F_SETOWN)

       (5)获取/设置记录锁(cmd = F_GETLK、F_SETLK或F_SETLKW)

         第三个参数是一个整数。

 

11.函数access

        #include  <unistd.h>

        int  access(const  char  *pathname,  int  mode);

     

       检查文件是否具有某种mode权限(读、写、执行)。

       函数成功返回0;函数失败返回-1。

 

12.函数chmod 

       #include   <sys/stat.h>

      int  chmod(const  char  *path,  mode_t  mode);

 

      修改文件权限;

      函数成功返回0;函数失败返回-1。

 

         或者直接在命令行使用。

        chmod    +   rwx/777    +   文件名

         chmod   +   u/g/o/a    +   +/-=    +     rwx    +     文件/目录

 

13.函数chgrp

       chgrp  -R  +  用户组  +  目录名/文件名

      改变目录/文件当前所在用户组。

      参数-R表示进行递归修改。如果是目录,则将目录里的所有文件、目录都改变。

 

14.函数chown

         chown   +   用户名    +    文件/目录名

         改变当前文件/目录的拥有者。

 

         chown   +   用户名:用户组    +    文件/目录名

          改变当前文件/目录的用户组和用户。

 

           chown   +   用户名.用户组    +    文件/目录名

           改变当前文件/目录的用户组和用户。

 

           chown   +   .用户组    +    文件/目录名

            改变当前文件/目录的用户组。

 

15.函数cp

           cp   +     源文件   +    新文件                 

           将源文件复制一份(包括复制执行者的属性和权限)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值