zoukankan      html  css  js  c++  java
  • inux学习之文件系统篇(二)

    文件系统(二)

    1.目录操作

    mkdir

    #include<sys/stat.h>

    #include<sys/types.h>

    int mkdir(const char *pathname,mode_t mode);

    创建一个目录

    rmdir

     #include<unistd.h>

    int rmdir(const char *pathname);

    删除一个目录

    opendir/fdopendir

     #include<sys/types.h>

    #include<dirent.h>

    DIR *opendir(const char *name);

    DIR *fdopendir(int fd);

    打开一个目录

     readdir

    #include <dirent.h>

    struct dirent *readdir(DIR *dirp);

    struct dirent   
    {   
      long d_ino; /* inode number 索引节点号 */  
         
        off_t d_off; /* offset to this dirent 在目录文件中的偏移 */  
         
        unsigned short d_reclen; /* length of this d_name 文件名长 */  
         
        unsigned char d_type; /* the type of d_name 文件类型 */  
         
        char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */

     readdir每次返回一条记录项,DIR* 指针指向下一条记录项。

     rewinddir

     #include<sys/types.h>

    #include <dirent.h>

    void rewinddir(DIR *dirp);

    把目录指针恢复到目录的起始位置

    telldir/seekdir

    #include<dirent.h>

    long telldir(DIR *dirp);

    #include <dirent.h>

    void seekdir(DIR *dirp,long offset);

     closedir

     #include<sys/types.h>

    #include <dirent.h>

    int closedir(DIR *dirp);

    练习:递归遍历目录(实现tree命令)

    #include<stdio.h>  
    #include <errno.h>  
    #include<stdlib.h>  
    #include<string.h>  
    #include <dirent.h>  
    #include <sys/types.h>  
    #include <sys/stat.h>  
    #include <unistd.h>  
      
    #define MAX_PATH 512  
      void dirwalk(char *dir,void(*fcn)(char *))  
    {  
        DIR *dfd;  
        char name[MAX_PATH];  
        struct dirent *dp;  
    if ((dfd = opendir(dir)) == NULL) { fprintf(stderr,"dir_walk: can't open %s %s", dir); return; } while ((dp = readdir(dir)) != NULL) { if (strcmp(dp->d_name, ".") == 0||strcmp(dp->d_name,".."==0) continue; /* 跳过当前目录和上一层目录以及隐藏文件*/ if (strlen(pathname) + strlen(dp->d_name) + 2 > sizeof(name)) { fprintf(stderr,"dir_order: name %s %s too long ", dir, dp->d_name); }
    else { memset(name, 0, sizeof(name)); sprintf(name, "%s/%s", dir, dp->d_name); (*fcn)(name); } } closedir(dfd); } void fsize(char *name) { struct stat stbuf; if (stat(name, &stbuf) == -1) { fprintf(stderr,"fsize:can't access %s ", name); return; } if ((stbuf.st_mode & S_IFMT) == S_IFDIR) //与后留下文件类型,若==S_IFDIR表示是一个目录 { dirwalk(name,fsize); } printf("%s %8ld ", stbuf.st_size, name); } int main(int argc, char **argv) { if (argc == 1) /*default:current directory /.app*/ { fsize("."); }
    else
    while(--argc>0) { fsize(*++argv);
    } return 0; }

    2.VFS虚拟文件系统

      Linux 中允许众多不同的文件系统共存,如 ext2, ext3, vfat 等。通过使用同一套文件 I/O 系统 调用即可对 Linux 中的任意文件进行操作而无需考虑其所在的具体文件系统格式;更进一步,对文件的 操作可以跨文件系统而执行。我们可以使用 cp 命令从 vfat 文件系统格式的硬盘拷贝数据到 ext3 文件系统格式的硬盘;而这样的操作涉及到两个不同的文件系统。“一切皆是文件”是 Unix/Linux 的基本哲学之一。不仅普通的文件,目录、字符设备、块设备、 套接字等在 Unix/Linux 中都是以文件被对待;它们虽然类型不同,但是对其提供的却是同一套操作界面。

      而虚拟文件系统正是实现上述两点 Linux 特性的关键所在。虚拟文件系统(Virtual File System, 简称 VFS), 是 Linux 内核中的一个软件层,用于给用户空间的程序提供文件系统接口;同时,它也提供了内核中的一个 抽象功能,允许不同的文件系统共存。系统中所有的文件系统不但依赖 VFS 共存,而且也依靠 VFS 协同工作。

    VFS

    VFS2

      打开一个文件首先是打开文件描述符,每个对应创建一个file结构体,f_op指向一组函数open,close,read,write...(是驱动层的操作,和应用层的不是一回事),这组函数对应具体的硬件操作,f_dentry指向磁盘文件,对应一组文件系统驱动。文件系统驱动和驱动层等这些都属于内核,上图的众多结构体相关联组成虚拟文件系统VFS。两个进程打开同一个文件,后写的覆盖前写的。若两个描述符指向同一个结构体,追加型。

    dup/dup2

    #include<unistd.h>

    int dup(int oldfd)

    int dup2(int oldfd,int newfd);

    dup和dup2都可用来复制现存的文件描述符,使两个文件描述符指向同一个file结构体。如果两个文件描述符指向同一个file结构体,file status flag和读写位置只保存一份在file结构体中,并且file结构体的引用计数会变为2。

    示例:

  • 相关阅读:
    死锁
    Notepad++源代码阅读——窗口封装与继承
    Notepad++源代码阅读——窗口元素组织与布局
    选择问题(selection problem)
    插入排序 | 冒泡排序 | 希尔排序 | 堆排序 | 快速排序 | 选择排序 | 归并排序
    编程之美2014---大神与三位小伙伴
    ulimit 修改 open files & core
    tmux手记
    匿名访问windows server 2008 R2 文件服务器的共享
    WINDOWS系统变量
  • 原文地址:https://www.cnblogs.com/rainbow1122/p/7809262.html
Copyright © 2011-2022 走看看