3 文件IO

一、文件描述符:内核通过文件描述符引用打开的文件,文件描述符是一个比较小的非负整数。

       打开或创建文件时,内核会向进程返回文件描述符

       读写一个文件时,open或create返回的文件描述符作为参数传给read或者write。

       按照惯例 UNIX系统shell关联方式如下:

            1)文件描述符0与进程的标准输入相关联

            2)文件描述符1与进程的标准输出相关联

            3)文件描述符2与进程的标准错误相关联

        使用符号常量可以增加程序的可读性<unistd.h>文件中定义了符号常量:

             STDIN_FILENO(0)、STDOUT_FILENO(1)、 STDERR_FILENO(2)

        文件描述符的范围是0-OPEN_MAX-1

二、函数open和openat:都可以打开和创建一个文件       

 #include<fcntl.h>

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

        int openat(int fd, const char *path, int oflag, ... /* mode_t mode */);

          注:   两函数的返回值:成功返回描述符,错误返回-1

                   参数 ... :ISO C用这种方法表明余下的参数的数量以及其类型是可变的

        path参数是文件名,oflag用下列一个或多个或运算构成:

               下列五种必须指定一个且只能指定一个

                  O_RDONLY、WRONLY、O_RDWR多数实现定义为0 1 2  ,O_EXEC(只执行打开),O_SEARCH

                下列是可选的:

                  O_APPEND: 每次写追加到文件尾端 

                  O_CLOEXEC: 把FD_CLOEXEC常量设置为文件描述符标志

                  O_CREAT:若文件不存在则创建。需要用mode参数指定权限

                  O_DIRECTORY : 如果path不是目录则出错

                  O_EXCL : 如果同时指定了 O_CREAT,而文件已经存在,则出错。用此可以测试文件是否存在

                  O_NOCTTY: 如果path已用终端设备,则不该将该设备分配作为此进程的控制终端

                  O_NOFOLLOW : 如果path引用的是符号链接,出错

                  O_NONBLOCK : 如果path引用的是一个FIFO、一个特殊文件或者一个字符特殊文件,则此项为文件的本次打开操

                                           作和后续的IO操作设置非阻塞方式

                  O_SYNC : 每次write等待物理IO操作完成

                  O_TRUNC : 如果此文件存在,而且为只读只写或读写操作成功打开,则长度截断为0

                  O_DSYNC : 每次write 要等待物理IO操作完成,但是如果该write操作不影响读取去刚写入数据,则不需等待

                  O_RSYNC : 使每一个以文件描述符为参数的read等待,直到所有对文件同一部分挂起的鞋操作完成

                O_TTY_INIT : 如果打开一个还未打开的终端设备,设置非标准 termios参数值,使其符合Single UNIX Specification

        fd参数:吧open和openat函数区分开,共有三种可能性

                1)path参数指定的是绝对路径名,fd参数被忽略,openat=open函数

                2)path参数指定的是相对路径名,fd参数指出了相对路径名在文件系统中的开始地址。fd参数是通过打开相对路径

                      名所在的的目录来获取

                3)path参数指定相对路径,fd参数设置成特殊值AT_FDCWD,路径名在当前工作目录中获取。

三、函数creat       

 #include<fcntl.h>

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

               // 注:成功返回只写打开的文件描述符,出错返回-1

        //此函数等效于:

        int open(path ,O_WRONLY|OCREAT|O_TRUNV, mode);

四、函数close

        #include<unistd.h>

        int close (int fd);

            注:成功返回0,失败返回-1

        关闭一个文件的同时还会释放该进程加在文件上的所有记录锁。当进程终止时,内核自动关闭它所有的打开文件。很多

         程序利用这一点不显示的调用close关闭文件

五、函数lseek(l标识long)     

  #include<unistd.h>

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

            注:成功返回新的文件偏移量,失败返回-1

        对于参数offset的解释与参数whence有关:

            1)whence 是 SEEK_SET,该文件的偏移量设置为距离文件开始处的offset个字节

            2)whence 是 SEEK_CUR,该文件的便宜设置为当前值加offset,offset可以

            3)whence 是 SEEK_END, 该文件的偏移量设置为文件长度加 offect,offset可正可负

        若lseek成功执行,则返回新的文件偏移量,为此可以用下列方式确定打开文件的当前偏移量

        off_t currpos;

        currpos = lseek(fd, 0, SEEK_CUR);

        这种方法也可以用确定设计的文件时否可以设置偏移量。如果文件描述符指向的是一个管道、FIFO 或网络套接字则lseek

            返回-1,并将errno设置为ESPIPE

六 函数read:调用read函数从打开的文件中读取数据     

  #include<unistd.h>

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

        如read成功,返回督导的字节数。如果已经达到文件尾返回0。

        有多重情况可以使实际读到的字节数少于要求读到的字节数:

        1 文件在要求读到的字节数就已经达到了尾端

        2 当从终端设备读取时,通常一次最多读一行

        3 当从网络读时,会因为网络的缓冲机制导致返回的长度小于要求的长度

        4 当从管道或者FIFO读时,如若管道包含的字节少于所需的数量

        5 当从某些面向记录的设备(如磁带)读时,一次最多返回一个记录

        6 当一个信号造成中断,而已经读了部分时

七、函数write    

  #include <unistd.h>

        ssize_t write (int fd, const void *buf, size_n bytes);

            注:成功返回写入的字节数,失败返回-1 

        返回值通常与nbytes的值相同,否则表示出错。write常见的出错原因是磁盘空间不足和超过一个给定进程的文件长度限制 

八、文件共享

        (1) 每个进程在进程表中都有一个记录项:

           (a) 文件描述符标志。

           (b) 指向一个文件表项的指针。

       (2) 文件表:

           (a) 文件状态标志(读、写、添写、同步和非阻塞等)。

            (b) 当前文件偏移量。

            (c) 指向该文件 V 节点表项的指针。

       (2) v-node v节点结构:

           (a) 文件类型

            (b) 对文件操作函数的指针

            (c) i节点, (文件的所有者、长度、指向文件所在磁盘位置的指针)

  

共享图:

 

九、dup和dup2

        复制文件描述符

#include<unistd.h>
int dup(int fd);
int dup2(int fd ,int fd2);
        #成功返回文件描述符,出错返回-1

 dup返回当前描可用文件描述符的最小值

dup2 可以用fd2指定新的文件描述符,如fd2已经打开,先关闭。如果fd等于fd2,返回fd2,不关闭

十、函数 

#include <unistd.h>
int fsync(int fd);
int fdatasync(int fd);
    #成功返回0,错误返回-1
void sync (void);

sync把修改过的块缓存排入写入队列,就返回,不等待实际写磁盘。通常称为update的系统守护进程周期性调用。

fsync 函数只对由文件描述符fd指定一个文件起作用,并且等待磁盘结束。可以应用到数据库

fdatasync 只影响数据部分数据,也就是说,它只保证开打文件的数据全部被写到物理设备上,但是一些元数据并不是一定的。

十 一、函数fcntl

#include<unistd.h>
int fcntl(int fd,int cmd,.../int arg */);

改变已经打开文件的属性

参数cmd:

  • F_DUPFD:复制文件描述符
  • F_DUPFD_CLOEXEC:复制文件描述符,新文件描述符被设置了close-on-exec
  • F_GETFD:读取文件描述标识
  • F_SETFD:设置文件描述标识
  • F_GETFL:读取文件状态标识
  • F_SETFL:设置文件状态标识
  • F_GETLK:如果已经被加锁,返回该锁的数据结构。如果没有被加锁,将l_type设置为F_UNLCK
  • F_SETLK:给文件加上进程锁
  • F_SETLKW:给文件加上进程锁,如果此文件之前已经被加了锁,则一直等待锁被释放。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值