APUE笔记 文件和目录

4.10 粘着位

     在早期的操作系统中,未使用分页技术。程序在磁盘上是随机存储的,则在装入程序是会耗费较大的时间,为保证下次执行程序时能将程序正文快装入内存,操作系统在磁盘上开辟了块交换区。交换区的文件是连续存储的,装入速度相对会更快。

     现在操作系统使用分页技术,因此不再使用这种技术。但一般都扩展了这个位:

     在文件的mod中S_ISVTX 位,表示粘着位,现代OS常用来限制一般用户对目录下文件的删除和重命名文件操作,但提供读写操作!

    现代OS中如果设置了目录I_SVTX位,则只有拥有写权限,且拥有下列之一的权限才能删除和重命名目录下文件:

      1.拥有文件

       2.拥有目录

       3.超级用户


4.11 修改文件所有者

    chown(const char* pathname, uid_t owner, gid_t group);

    fchown(int fd,  uid_t owner, gid_t group);

    fchownat(int fd, const char* pathneme, uid_t owner, gid_t group, int flag);

    lchown(const char* pathname, uid_t owner, gid_t group);

    四个函数修改文件的用户ID,组ID;

  1.     当owner 或group 有一个是-1时,id不变(owner,group 都不变)
  2.     _POSIX_CHOWN_RESTRICTED:
  3.     有两种关于文件修改权限的情况:
  •          只有超级用户才能修改owner
  •          允许用户修改,对修改加以限制(设置了_POSIX_CHOWN_RESTRICTED ,只修改自己拥有的文件的组ID到,用户所属的组当前或者其他组)      





4.17符号链接

   1)  符号链接相对硬链接而言,硬连接是直接指向inode,而符号链接是在文件的数据中记录了文件的名字。

   硬连接的限制:

    1.只能指向同一文件系统(符号链接不是指向的inode所以可以指向任意系统)    2.指向目录的硬连接只能由内核执行(OS支持的前提下),为了防止循环链接(符号链接也能引起循环,一般查找路径的函数会错误返回,相比硬连接的文件系统错误,此错不会这么致命)

   2)在处理文件时候要注意函数是否具有处理链接的能力

     1.一般l开头的都直接处理链接不延伸到所指文件,lstat,lchown。。

     2.f开头的函数以fd为处理参数,对于链接处理的控制优open完成(open打开是处理所指文件,openat可指定是否follow链接)。

     3.mdir,rmdir,mkinfo,mknod则在处理链接时直接返回-1

   3)符号链接可能导致指向不存在的文件,链接是不会检查!

csl@ubuntu:~$ ln -s /no/file nofile
csl@ubuntu:~$ ls 
csl@ubuntu:~$ cat nofile 
cat: nofile: No such file or directory
csl@ubuntu:~$ 

文件ls显示存在nofile ,却读不出来
4.18创建&读取符号链接

创建链接

int symlink(const char* actualpath, const char* symblpath);

int symlinkat(int fd, const char * actualpath, int symfd, const char*sympath);

打开链接本身,不读所指文件

int readlink(const char* sympath,char *rstrict buf, size_t size);

int readlinkat(int fd, const char* sympath, char* buf, suze_t size );

4.19文件时间

st_atime 系统的最近访问时间,注意之际录数据的访问时间,对属性修改不会记录

st_ctime 系统的最近修改时间,记录的是文件inode的修改时间也就算属性的修改时间,系统不记录inod的访问时间,也就是访问系统哦功能属性时时间不会记录

st_mtime 文件数据的最近修改时间



遍历文件目录

#include <iostream>
#include <unistd.h>
#include <sys/stat.h>//S_ISDIR
#include <stdlib.h>
#include <string.h>
#include <dirent.h>//dirent DIR
using namespace std;


int c = 2;
const int MAX = 256;
char *path;
int pathlen;
static void dopath();

static void myftw(const char *pathname)
{
    //cout << pathname<<endl;
    if((path = (char *)malloc(MAX)) != 0)
    {
        pathlen = 256;
    }
    else
    {
           cout << "分配内存失败!"<<endl;
           return ;
    }

    if(pathlen < strlen(pathname))
    {
        pathlen *= 2;
       if(( path = (char *)realloc(path, pathlen)) == 0)
           {
               cout << "内存 出毛病了!"<<endl;
               return ;
           }
    }
    strcpy(path, pathname);
    dopath();
}

static void dopath()
{

     struct stat statbuf;
     if(lstat(path, &statbuf) < 0)
     {
               cout << "stat 出毛病了!"<<endl;
               return ;
    }

    if(S_ISDIR(statbuf.st_mode) == 0)// 判断是不所目录
    {
        for(int i = 0; i < c; i++)cout << "  ";
        cout << path<<endl;
        return;
    }

    int n = strlen(path);
    if(n + NAME_MAX + 2 >  pathlen)
    {
        pathlen = max(n + NAME_MAX + 2 , pathlen * 2 );
        path = (char *)realloc(path, pathlen);
    }
    path[n++] = '/';
    path[n] = 0;
    for(int i = 0; i < c; i++)cout << "  ";
    cout << path<<":"<<endl;
    DIR *dirp;
    if((dirp = opendir(path)) == NULL)//
    {
        cout <<  "dir open faild!!!"<<endl;
        return;
    }
  //  sleep(1);
    struct dirent *direp;
    int i = 0;
     while((direp = readdir(dirp))  != NULL)//逐条读取文件目录,直到文件末尾
     {
         if(strcmp(direp->d_name, ".") == 0 || strcmp(direp->d_name, "..") == 0 )continue;
         strcpy(path + n, direp->d_name);
          c+= 2;
         dopath();
          c-=2;

     }  path[n - 1] = 0;
          closedir(dirp);

}

int main(int argc, const char *args[])
{
    myftw(args[1]);
    cout << "Hello world!" << endl;
    return 0;
}


4.24特殊设备(待研究)

st_dev ,st_rdev  通常dev_t 高为表示主设备号,低若干位表示次设备号

每个文件系统所在的存储系统主次设备号

主设备号标示驱动程序

次设备号标示特定子设备

只有字符设备& 块设备才有st_rdev 值

major  minor两个宏可的主次设备号值



du & df

du -sh命令通过将指定文件系统中所有的目录、符号链接和文件使用的块数累加得到该文件系统使用的总块数;

而df命令通过查看文件系统磁盘块分配图得出总块数与剩余块数
文件系统分配其中的一些磁盘块用来记录它自身的一些数据,如i节点,磁盘分布图,间接块,超级块等。这些数据对大多数用户级的程序来说是不可见的,通常称为Meta Data。
du命令是用户级的程序,它不考虑Meta Data,而df命令则查看文件系统的磁盘分配图并考虑Meta Data。

因此正常情况下,df计算的USED空间会比du计算的结果要稍大。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值