Ubuntu下UnixC的第六天

回忆
一、lseek(2) 重新定位读写文件的位置
二、使用mmap将文件映射到进程的虚拟地址空间
在内存中对数据的更改直接反应到文件中
三、文件描述符的复制
dup (2)
dup2(2)
文件描述符的具体概念
文件输出重定向
文件输入重定向
四、获取文件的元数据
inode  i节点 每个文件都有自己的inode  且是唯一的
硬链接  软链接 原理
stat(2) struct stat结构体
uid gid 时间的处理 ctime
根据uid 和gid找到用户名字和用户组名字
结构体 成员  值-结果参数

权限的问题
文件类型

今天的内容:
一 获取文件的元数据(文件类型和权限)
-rw-rw-r-- 1 nan nan 615 1月  10 10:25 笔记
第一个字符代表文件的类型
-   普通文件
d   文件夹
c   字符设备文件
b   块设备文件
l   软连接文件
s   socket文件
p   管道文件
    
rw-rw-r-- 
属主owner   属组   other
 40775
170000
111
4
二 文件夹的操作
    427171 drwxrwxr-x 2 nan nan  4096 1月  10 11:34 hello
    rwx
    x 可通过
    r w 文件夹的内容是什么
    文件夹的内容就是文件夹里的文件或者文件夹
    如何才算对文件夹的内容进行写操作
    删除文件   新建文件

    使用函数对文件夹里的内容进行读操作(遍历)
    opendir(3)
     #include <sys/types.h>
       #include <dirent.h>

       DIR *opendir(const char *name);
    功能:打开一个文件夹
    参数:
    name:指定了文件夹的名字
    返回值:返回一个指向文件夹流的指针,指向文件夹下的第一个条目
        错误时返回NULL errno被设置
    closedir(3)
     #include <sys/types.h>

       #include <dirent.h>

       int closedir(DIR *dirp);
    功能:关闭文件夹
    参数: 
    dirp 指定要关闭的文件夹流
    返回值:成功返回0
        错误 -1  errno被设置


    readdir(3)
     #include <dirent.h>

       struct dirent *readdir(DIR *dirp);
    功能:从文件夹读取一个文件夹条目
    参数 
    dirp 指定了文件夹流
    返回值:成功返回指向结构体的指针
        返回NULL   到达了文件夹的末尾或者错误    
        如果是错误  errno被设置   
    
 struct dirent {
               ino_t          d_ino;       /* inode number */
               off_t          d_off;       /* not an offset; see NOTES */
               unsigned short d_reclen;    /* length of this record */
               unsigned char  d_type;      /* type of file; not supported
                                              by all filesystem types */
               char           d_name[256]; /* filename */
           };
    


      cJSON
      docker容器
    

三 文件锁的使用
    两种  读锁(共享锁)  写锁(互斥锁)
    锁的实现又分为两种   建议锁  强制锁
如何使用文件锁
 #include <unistd.h>
       #include <fcntl.h>

       int fcntl(int fd, int cmd, ... /* arg */ );
功能:
参数:
    fd 指定了要操作的文件操作符
    cmd 
    F_SETLK  设置一把锁 加锁,如果有互斥锁,立即返回-1, errno被设置
    F_SETLKW   设置一把锁,加锁  如果有互斥锁 等待这把锁被释放
    F_GETLK    测试是否可以放置锁 如果返回的lock的l_type里是F_UNLOCK,说明可以放置锁。如果有其他进程已经放置互斥锁,返回持有该互斥锁的进程的pid到lock的l_pid字段里
    ... 可变参数  参数的个数 类型 取决于cmd
    
返回值:成功 0
    错误 -1 errno被设置

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
                                   (set by F_GETLK and F_OFD_GETLK) */
               ...
           };
编写代码如下   pa.c 完成对指定文件加读锁
          pb.c完成对指定文件加写锁
          pc.c测试文件是否可以加读锁
四 库函数和系统调用的关系
    fopen(3) fclose(3) fputc(3)  fgetc(3)
    open  read write  close
    演示代码 file.c
    fopen(3)首先为FILE类型的变量分配空间,然后分配一块用于文件操作的缓冲区。将缓冲区中的相应地址记录到FILE类型的变量空间的字段里。调用open,返回文件描述符,记录在fileno中。
    fgetc(3) 从参数中找到读取数据的缓冲区,从中读取数据,如果空间里有数据,立即返回,如果没有数据,调用read(2)从文件中读取数据到缓冲区,然后,fgetc获取到数据,立即返回。
    fputc(3)从参数中找到存放数据的缓冲区,如果有足够的空间,将数据放入缓冲区,立即返回,如果缓冲区空间不足,调用write(2)将缓冲的数据写入到文件,清空缓冲区,fputc将数据放入到缓冲然后返回
    fclose(3)首先将缓冲区中的数据同步到文件中,释放缓冲区,调用close(2)关闭文件描述符fileno。释放FILE类型变量的空间。
    库函数封装了系统调用
    缓冲文件,非缓冲文件
    库函数的效率比较高,可以跨操作系统。
五 文件操作的杂项
    access(2)
    getcwd(3)
    chdir(2)
    mkdir(2)
    rmdir(2)
    basename(3)
    dirname(3)
    link(2)硬链接
    unlink(2)
    chmod(2)
    rename(2)
    remove(3)
    symlink(2)
 

 

t_ls.c

#include<t_stdio.h>
#include<t_file.h>
#include<dirent.h>
int main(int argc,char* argv[]){
    //打开文件夹
    DIR *dir=opendir(".");
    if(!dir) E_MSG("open",-1);


    while(1){
    struct dirent *p=readdir(dir);

    if(!p)break;
    if(p->d_name=="."||p->d_name=="..")
        continue;
    printf("%s   ",p->d_name);
    }
    printf("\n");
    closedir(dir);
    return 0;
}
 

 

stat.c

#include<t_stdio.h>
#include<t_file.h>
#include<time.h>
#include<pwd.h>
#include<grp.h>
int main(int argc,char *argv[]){
    //获取文件的元数据,存储到buf
    struct stat buf;

    int s=stat(argv[1],&buf);
    if(s==-1) E_MSG("stat",-1);
    
    
    printf("hard links:%u\n",buf.st_nlink);
    printf("size:%ld\n",buf.st_size);
    printf("inode:%ld\n",buf.st_ino);
    printf("mtime:%s",ctime(&buf.st_mtime));
    printf("uid:%u\n",buf.st_uid);
    printf("username:%s\n",(getpwuid(buf.st_uid))->pw_name);
    printf("gid:%u\n",buf.st_gid);
    printf("group grname:%s\n",(getgrgid(buf.st_gid))->gr_name);
    printf("mode:%o\n",buf.st_mode);
    switch(buf.st_mode&S_IFMT){
        case S_IFDIR:
                printf("d");
                break;
        case S_IFREG:
                printf("-");
                break;
        default:
                break;
    
    }
    (buf.st_mode&S_IRUSR)?printf("r"):printf("-");
    (buf.st_mode&S_IWUSR)?printf("w"):printf("-");
    (buf.st_mode&S_IXUSR)?printf("x"):printf("-");
    
    (buf.st_mode&S_IRGRP)?printf("r"):printf("-");
    (buf.st_mode&S_IWGRP)?printf("w"):printf("-");
    (buf.st_mode&S_IXGRP)?printf("x"):printf("-");
    
    (buf.st_mode&S_IROTH)?printf("r"):printf("-");
    (buf.st_mode&S_IWOTH)?printf("w"):printf("-");
    (buf.st_mode&S_IXOTH)?printf("x"):printf("-");
    printf("\n");
    return 0;
}
 

pa.c

#include<t_stdio.h>
#include<t_file.h>
#include<fcntl.h>

int main(int argc,char* argv[]){
    //给指定文件加读锁 argv【1】传递
    int fd=open(argv[1],O_RDONLY|O_CREAT);
    if(fd==-1) E_MSG("OPEN",-1);
    
    struct flock lock;    
    //初始化lock
    lock.l_type=F_RDLCK;
    lock.l_whence=SEEK_SET;
    lock.l_start=0;
    lock.l_len=6;
    int f=fcntl(fd,F_SETLK,&lock);
    if(f==-1) E_MSG("fcntl",-1);
    printf("read lock...\n");
//加写锁
    
    lock.l_type=F_WRLCK;
    lock.l_whence=SEEK_SET;
    lock.l_start=0;
    lock.l_len=6;
     fd=open(argv[1],O_WRONLY|O_CREAT);
    f=fcntl(fd,F_SETLK,&lock);
    if(f==-1) E_MSG("fcntl",-1);
    printf("write lock...\n");
    

    
    getchar();//保证当前进程不关闭,锁不消失
        //关闭文件描述符时,所有记录锁就没了
    
    

    close(fd);
    return 0;
}
 

pb.c

#include<t_stdio.h>
#include<t_file.h>
#include<fcntl.h>

int main(int argc,char* argv[]){
    //给指定文件加读锁 argv【1】传递
    int fd=open(argv[1],O_WRONLY|O_CREAT);
    if(fd==-1) E_MSG("OPEN",-1);
    
    struct flock lock;    
    //初始化lock
    lock.l_type=F_WRLCK;
    lock.l_whence=SEEK_SET;
    lock.l_start=0;
    lock.l_len=6;
    int f=fcntl(fd,F_SETLK,&lock);
    if(f==-1) E_MSG("fcntl",-1);
    printf("WRITE lock...\n");
    getchar();//保证当前进程不关闭,锁不消失
        //关闭文件描述符时,所有记录锁就没了
    if(f==-1) E_MSG("fcntl",-1);
    

    close(fd);
    return 0;
}
 

pc.c

#include<t_stdio.h>
#include<t_file.h>
#include<fcntl.h>

int main(int argc,char* argv[]){
    //给指定文件加读锁 argv【1】传递
    int fd=open(argv[1],O_RDONLY|O_CREAT);
    if(fd==-1) E_MSG("OPEN",-1);
    
    struct flock lock;    
    //初始化lock
    lock.l_type=F_RDLCK;
    lock.l_whence=SEEK_SET;
    lock.l_start=0;
    lock.l_len=6;
    int f=fcntl(fd,F_GETLK,&lock);
    if(f==-1) E_MSG("fcntl",-1);
    if(lock.l_type==F_UNLCK)
    printf("may read lock\n");
    else 
        printf("block proccess pid is%d\n",lock.l_pid);

        //关闭文件描述符时,所有记录锁就没了
    if(f==-1) E_MSG("fcntl",-1);
    

    close(fd);
    return 0;
}
 

file.c

#include<t_stdio.h>
int main(int argc,char*argv[]){
    FILE *fp=fopen(argv[1],"r");
    if(fp==NULL) E_MSG("open",-1);
    fclose(fp);
    return 0;
}
 

dir.c

#include<t_stdio.h>
#include<t_file.h>
#include<dirent.h>
int main(int argc,char* argv[]){
    //打开文件夹
    DIR *dir=opendir(argv[1]);
    if(!dir) E_MSG("open",-1);
    printf("open dir success...\n");
//关闭文件夹
    while(1){
    struct dirent *p=readdir(dir);

    if(!p)break;
    printf("file:%s\t inode:%lu\n",p->d_name,p->d_ino);
    }
    closedir(dir);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值