zoukankan      html  css  js  c++  java
  • dup、文件锁、库函数、函数调用(day07)

    一、lseek(2)重新定位文件的读写位置。
    #include <sys/types.h>
    #include <unistd.h>
    off_t lseek(int fd,  off_t  offset,  int whence);
    功能:重新定位文件读写位置距离文件起始的偏移
    参数:
    fd:指定了具体的文件
    offset:偏移
    whence:
    SEEK_SET:offset就是文件的偏移位置   指向文件的头部
    SEEK_CUR:代表当前位置   当前位置+offset
    SEEK_END:文件的大小+offset     文件的尾部
    返回值:
    -1   错误   errno被设置
    返回的是位置距离文件起始的字节数。
    举例说明  lseek(2)的使用.代码参见  lseek.c
    
    补充:
    day07$od -tx1 -tc hello
    0000000  68  65  6c  6c  6f  0a
              h   e   l   l   o  
    
    0000006
    
    day07$vi hello
    day07$od -tx1 -tc hello
    0000000  68  65  6c  6c  6f  0a  77  6f  72  6c  64  0a
              h   e   l   l   o  
       w   o   r   l   d  
    
    0000014
    
    二、使用mmap将文件映射到进程的虚拟地址空间,然后对内存的操
    作直接反应到文件中。
    将文件hello映射到内存,在内存中对文件的内容进行修改,改变实际文件的内容。
    代码参见  mmap_file.c
    
    三、文件的重定向
    什么是文件的重定向?
    我们讲述的文件是流式文件。操作的都是文件流。文件的重定向就是改变文件的流向。文件操作有两种流,输入流和输出流。
    文件重定向分为文件输出重定向和文件输入重定向。
    文件输出重定向。
    完成文件描述符复制的两个系统调用
    dup(2)   dup2(2)
    #include <unistd.h>
    int dup(int oldfd);
    功能:复制文件描述符
    参数:
    oldfd:源文件描述符
    返回值:
    -1  错误 errno被设置
    返回最小的、没有被使用的文件描述符
    
    int dup2(int oldfd, int newfd);
    功能:复制文件描述符
    参数:
    oldfd:源文件描述符
    newfd:目的文件描述符
    返回值:
    -1  错误 errno被设置
    成功返回目的文件描述符
    
    举例说明  使用dup(2)和dup2(2)实现文件的输出重定向。
    代码参见   direct.c
    
    
    四、文件锁的使用
    文件锁分为两种    读锁(共享锁)        写锁(互斥锁)
    文件对锁的实现分为两类     建议锁     强制锁
    如何对文件加锁?
    使用系统调用fcntl(2)对文件进行加锁。
    #include <unistd.h>
    #include <fcntl.h>
    int fcntl(int fd, int cmd, ... /* arg */ );
    功能:操作文件描述符
    参数:
    fd:指定要操控的文件描述符
    cmd:指定了操作文件描述符的命令
    建议锁使用的命令:
    F_GETLK:用来测试是否可以加锁,如果可以加锁,返回F_UNLCK。
    不可以加锁,在字段l_pid中保存了一个pid。是hold着这把锁的进程的pid。
    
    F_SETLK:为文件描述符设置锁。如果有互斥锁,其他进程hold着互斥锁,立即返回-1,错误,errno被设置
    
    F_SETLKW:和F_SETLK一样,但是如果想要加的锁和文件已有记录锁冲突,进程阻塞等待其他进程对记录锁的释放。
    
    ...:  可变参数,参数的类型和个数取决于cmd。
    struct flock *
    struct flock {
                   ...
            short l_type;   /* Type of lock: F_RDLCK,
                                       F_WRLCK, F_UNLCK */
            short l_whence;  /* How to interpret l_start:
                           SEEK_SET, SEEK_CUR, SEEK_END */
            off_t l_start; /* Starting offset for lock */
            off_t l_len;     /* Number of bytes to lock */
         pid_t l_pid; /* PID of process blocking our lock
                            (F_GETLK only) */
                   ...
    };
    
    返回值:
    0  成功
    -1  错误   errno被设置
    
    举例说明文件锁的使用
    有两个进程PA和PB,PA进程对文件加读锁,测试PB进程对同一个文件也加读锁,是否成功?
    代码参见  PA.c PB.c
    
    测试文件锁是否能添加。代码参见PC.c
    
    五、库函数和系统调用之间的关系
    以文件操作为例。
    fopen    fclose     fputc   fgetc   库函数
    open     close      read    write   系统调用
    
    举例说明   代码参见 file.c
    
    FILE    是结构体类型的别名
    
    flags   fileno   mode  
    
    fopen(3)
    首先调用open(2),打开一个文件,将open(2)的返回值记录在FILE结构体中的_fileno成员。分配一块内存,这块空间叫文件内容缓冲区。然FILE中的一些指针成员指向这块内存。最后返回FILE类型的对象。
    
    fputc(3)
    调用fputc的时候,向文件内容缓冲区写数据。如果缓冲区没有空间接纳这个字符,调用write(2)将缓冲区的数据写入到文件中,然后再将fputc中的数据写入到缓冲区。如果缓冲有空间接纳数据,直接将数据写入缓冲区即可。
    
    fgetc(3)
    调用fgetc的时候,首先从缓冲区读取数据,如果缓冲区有数据,理解返回读取到的字节。如果缓冲区没有数据,调用read(2)从文件中读取数据 到缓冲区,然后fgetc了获取到数据才返回。
    
    
    fclose(3)
    首先刷新缓冲区,将缓冲区内存写入到文件中,然后调用close(2)关闭文件描述符,最后释放缓冲区。
    
    库函数操作文件称为缓冲文件。
    系统调用操作文件称为非缓冲文件
    
    库函数可以跨平台    系统调用不能跨平台
    
    总结:
    一、lseek的使用
    二、使用mmap将文件映射到内存,对内存的操作直接反应到文件中
    三、文件输出重定向
    四、文件锁的使用
    五、库函数和系统调用之间的关系
  • 相关阅读:
    .NET日期格式化
    Win7 计算机(我的电脑)右键菜单“管理”打不开,解决方法
    没有对“Temporary ASP.NET Files”的写访问权限
    Android安装jsk出错
    WPF 处理 系统Scale参数
    WPF WindowChrome 自定义标题栏时窗体阴影效果设置
    使用WindowChrome 在切换ResizeMode值时的问题
    Vue.js provide / inject 踩坑
    MYSQL 查询日期最大的那条记录
    所有子一级元素添加阴影
  • 原文地址:https://www.cnblogs.com/Kernel001/p/7732581.html
Copyright © 2011-2022 走看看