Unix环境高级编程第三章:文件IO

APUE主要讨论了三部分内容:文件IO、并发、进程间通信

• 文件IO:
标准IO:优点是可移植性高,缺点是性能比系统 IO 差,且功能没有系统 IO 丰富。
系统IO:因为是内核直接提供的系统调用函数,所以性能比标准 IO 高,但是可移植性比标准 IO 差。

• 并发:
信号 + 多进程;
多线程;
进程间通信:
FIFO:管道;
 System V:又称为 XSI,支持以下三种方式:
 msg:消息队列;
 sem:信号量;
 shm:共享存储;
 Socket:套接字(网络通信);

• 文件描述符
对于内核而言,所有打开的文件都是通过文件描述符引用,文件描述符是一个非负整数。当打开或者创建一个新文件时,内核向进程返回一个文件描述符。当读写一个文件时,使用open或creat返回的文件描述符标识该文件,将其作为参数传送给read或write。

• 文件IO函数
1:lseek(设置文件偏移量)

#include
off_t lseek(int fd,off_t offset,int whence)   //返回值: 若成功,返回新的文件偏移量 若出错 返回-1

每个打开文件都有一个与其相关联的“当前文件偏移量”。它通常是一个非负整数,用以度量从文件开始处计算的字节数,通常读写都从当前文件偏移量处开始,并使偏移量增加所读写的字节数。
2:write(向打开的文件写数据)

#include
ssize_t write(int fd,const void* buf,size_t nbytes)//返回值:若成功 返回已经写的字节数 若出错 返回-1

3:read函数(从打开的文件中读数据)

#include
ssize_t read(int fd,void* buf,size_t nbytes)//返回值: 读到的字节数,若已到文件尾 返回0;若出错,返回-1

做个例子熟悉下这几个函数吧

  1 #include"apue.h"
  2 #include
  3 #include
  4 #include
  5 
  6 int main()
  7 {
  8     int fd,byteNum,result;
  9     char wbuf[10] = "123456789";
 10     if((fd=open("./a.txt",O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IXUSR))<0){
 11         perror("Fail to open\n");
 12     }else{
 13         printf("open\n");
 14     }
 15     if((byteNum=write(fd,wbuf,10))<0){
 16         perror("Fail to write\n");
 17         return -1;
 18     }else{
 19         printf("byteNum - %d\n",byteNum);
 20     }
 21 }

在这里插入图片描述

      1 #include"apue.h"
      2 #include
      3 #include
      4 #include
      5 
      6 int main()
      7 {
      8     int fd,byteNum,result;
      9     char wbuf[10] = "123456789";
     10     char nbuf[5] = "ABCDE";
     11     if((fd=open("./a.txt",O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IXUSR))<0){
     12         perror("Fail to open\n");
     13     }else{
     14         printf("open\n");
     15     }
     16     if((byteNum=write(fd,wbuf,10))<0){
     17         perror("Fail to write\n");
     18         return -1;
     19     }else{
     20         printf("byteNum - %d\n",byteNum);
     21     }
     22     if((byteNum=write(fd,wbuf,3))<0){
     23         perror("Fail to write\n");
     24         return -1;
     25     }else{
     26         printf("byteNum - %d\n",byteNum);
     27     }
     28     return 0;
     29 }

在这里插入图片描述
此时的文件:
在这里插入图片描述

   1 #include"apue.h"
      2 #include
      3 #include
      4 #include
      5 
      6 int main()
      7 {
      8     int fd,byteNum,result;
      9     char wbuf[10] = "123456789";
     10     char nbuf[5] = "ABCDE";
     11     if((fd=open("./a.txt",O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IXUSR))<0){
     12         perror("Fail to open\n");
     13     }else{
     14         printf("open\n");
     15     }
     16     if((byteNum=write(fd,wbuf,10))<0){
     17         perror("Fail to write\n");
     18         return -1;
     19     }else{
     20         printf("byteNum - %d\n",byteNum);
     21     }
     22 
     23     //lseek
     24     if((result = lseek(fd,4,SEEK_SET))<0){
     25         perror("Fail to lseek\n");
     26     }else{
     27         printf("New offet of this file:%d\n",result);
     28     }
     29     return 0;
     30 }

在这里插入图片描述

 30     //read
 31     if((byteNum = read(fd,rbuf,12))<0){
 32         perror("Fail to read\n");
 33     }else{
 34         printf("byteNum = %d\n",byteNum);
 35     }
 36     return 0;

在这里插入图片描述
读到了文件终结符,因为wbuf只给了9个字符,在write后第十个字符变成了EOF。
• 文件共享
Unix环境高级编程第三章:文件IO_第1张图片
打开文件的内核数据结构(抄别人的图)
Unix环境高级编程第三章:文件IO_第2张图片
两个进程同时打开一个文件(抄别人的图)

我们假定第一个进程在文件描述符3上打开该文件,而另一个进程在文件描述符4上打开该文件,打开该文件的每一个进程都会获得各自的一个文件表项,但对于一个给定的文件只有一个v节点表项。之所以每个进程都获得自己的文件表项,是因为这可以使每个进程都有它自己的对该文件的当前偏移量。
当多个进程同时操作一个文件时,可能会产生预想不到的后果,需要通过原子操作来解决。
• 原子操作
对于原子操作重点在于理解概念啦,pread和pwrite就不demo了,多线程玩的不熟,有时间在补充。
一般而言,原子操作指的是由多步组成的一个操作。如果该操作原子地执行,则要么全部执行,要么全部不执行。(这个概念实在太常见,数据库的事件,操作系统的PV操作。。。)

好了,公司阿姨关灯撵我走,后面的巴拉巴拉函数有空在demo吧,突然怀恋实验室。

你可能感兴趣的:(unix环境高级编程)