您的位置:首页 > 产品设计 > UI/UE

APUE笔记 文件和目录

2015-03-25 11:23 429 查看
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;

    当owner 或group 有一个是-1时,id不变(owner,group 都不变)
    _POSIX_CHOWN_RESTRICTED:
    有两种关于文件修改权限的情况:
         只有超级用户才能修改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
= 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计算的结果要稍大。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: