umask
umask是一个命令,可以得到当前的umask值
作用:防止产生权限过松的文件
也有同名函数
文件权限的管理/更改
Chmod:chmod 666 .c(文件)
改变一个文件的权限
fchmod:
以上都有同名函数
文件系统:FAT,UFS
定义:文件或是数据的存储格式问题和管理
FAT16/32:是一个静态存储的单链表
单链表最大的缺陷是单向的,承载能力有限
轻量级,比较容易实现
UFS:
实际生产环境当中一块的大小4K起步
一个文件的几乎所有信息都存放在一个文件的inode当中
Inode它是一个结构体
Struct
{
stat
亚数据信息
隐藏起来的文件(与本文件无关的内容)
指针组(有15个指针,前十二个叫做直接的数据块指针,后面的三个指针,分别为一级的间接块指针,二级的间接块指针,三级的间接块指针)
//十二个指针都指向我们所说的那个1K的块,如果超过12K就会用到间接指针,间接指针也会指向1K的小块,若当前的环境是32位的,那么这块空间就可以存放256个指针(指针是4字节的),每一个指针还是指向1K的小块
}
有可能inode耗尽了,但是,数据块还是大段的空白,
大量小文件的查找比较麻烦
怎么知道当前的inode用了还是没用?
这个时候就用到inode位图
inode位图和inode的块是一样的,里面是0和1,通过0和1确定inode用还是没用。
块位图里面有多少格子也是和块数据一样的,也是0和1来表示用还是没用
可参考下面博主的博客(https://blog.csdn.net/qq2208889900/article/details/111240191)
inode几乎存储了文件的所有信息,但是文件名没有在里面
文件名在目录文件,这里面有目录项,一条目录项包含inode,和文件名,目录文件存放在任何的目录下。
如果找了这样一个文件其实知道根在哪就可以
inode为2的是根,根下的文件的etc的inode就知道,然后根据etc
目录下的文件找到下一个inode
/etc/···/···/···/···/
硬链接,符号链接
做一个硬链接:ln sourcefile destinationfile
如果删除源文件,也是可以看出destinationfile的属性
属性和源文件是一样的(类似两个指针指向了同一个数据块
硬链接就是目录项的同义词
建立硬链接有限制,不能给分区建立,不能给目录建立。
符号链接ln -s sourcefile destinationfile
得到的destinationfile 属性和源文件不同,硬链接数也不会增加,
文件的size也不一样(和名字的长度一样大),不占空间大小
删除源文件,和得到非法的指向,告诉你源文件已经失效了
可以跨分区,可以给目录创建
相关函数:
link
----------------------------- make a new name for a file
#include <unistd.h>
int link(const char *oldpath, const char *newpath);
unlink
------------------------------- - delete a name and possibly the file it refers to
#include <unistd.h>
int unlink(const char *pathname);
在磁盘删掉一个文件,用rm删除,前提条件是这个文件的硬链接数为0,或是没有进程打开这个文件使用,那块数据空间才会被释放
只要有内容引用到那个数据块,那块空间就没有被删除
unlink容易让我们产生一个匿名文件
加入用tmpname获得一个可用的名字,然后马上调用open
这时候我们就会拿到文件描述符,这个时候马上执行unlink
把这个文件从磁盘上删除,但是这个文件不会被直接释放,因为open了,直到我们close文件描述符,才会从磁盘上删掉。这样也就减少了命名冲突的可能性,因为是创建出来以后又马上unlink,从磁盘上删除了,所以这个文件存在磁盘上的时间是一闪而过的。
utime
更改时间
utime
-------------- change file last access and modification times
最后读的时间和最后写的时间
#include <sys/types.h>
#include <utime.h>
int utime(const char *filename, const struct utimbuf *times);
目录的创建和销毁
mkdir
mkdir, mkdirat - create a directory
#include <sys/stat.h>
#include <sys/types.h>
int mkdir(const char *pathname, mode_t mode);
rmdir
---------------- deletes a directory, which must be empty.
#include <unistd.h>
int rmdir(const char *pathname);
切换目录/更改当前工作路径
chdir
chdir, fchdir - change working directory
#include <unistd.h>
int chdir(const char *path);
int fchdir(int fd);
chroot
假根技术
getcwd(pwd)
-----------------------------------get current working directory
#include <unistd.h>
char *getcwd(char *buf, size_t size);
读取目录内容/分析目录
glob()://解析模式或是通配符
-------- find pathnames matching a pattern, free memory from glob()
#include <glob.h>
int glob(const char *pattern, int flags, int (*errfunc) (const char *epath, int eerrno), glob_t *pglob);
void globfree(glob_t *pglob);
//第三个参数是指向函数的指针,保存当前出错的路径和出错的原因,
当解析的pattern出现问题,如果出错了就在第三个参数里面放一个函数的入口地址,
如果不需要,则用NULL,解析的结果放到最后一个参数当中.
glob_t结构体:
typedef struct {
size_t gl_pathc; /* Count of paths matched so far */
一个计数器,计算出和pattern相配的名字又多少个
char **gl_pathv; /* List of matched pathnames. */
和pattern相匹配的名字都放在这儿
size_t gl_offs; /* Slots to reserve in gl_pathv. */
//前两个成员很像argc,argv
} glob_t;
一些flag(具体可以自己man查看)
flags:
The argument flags is made up of the bitwise OR of zero or more the following symbolic constants, which modify the behavior of glob():
GLOB_ERR
Return upon a read error (because a directory does not have read permission, for example). By default, glob() attempts carry on despite errors, reading all of the directories that it can.
GLOB_MARK
Append a slash to each path which corresponds to a directory.
GLOB_NOSORT:(先解析出来哪个就打印哪个
Don’t sort the returned pathnames. The only reason to do this is to save processing time. By default, the returned pathnames are sorted.
GLOB_DOOFFS
Reserve pglob->gl_offs slots at the beginning of the list of
strings in pglob->pathv. The reserved slots contain null point‐
ers.
GLOB_NOCHECK:(没有匹配项,将会返回pattern本身
If no pattern matches, return the original pattern. By default, glob() returns GLOB_NOMATCH if there are no matches.
GLOB_APPEND:(追加,如果使用就是对最后参数的内容进行追加,否则就是覆盖写)
Append the results of this call to the vector of results returned by a previous call to glob(). Do not set this flag on the first invocation of glob().
返回值:
On successful completion, glob() returns zero.Other possible returnsare:
GLOB_NOSPACE
for running out of memory,
GLOB_ABORTED
for a read error, and
GLOB_NOMATCH
for no found matches.
例子:
代码功能:查看/etc/a*.conf
/etc下面以a开头的.conf文件有多少各?
#include <stdio.h>
#include <stdlib.h>
#include <glob.h>
#define PAT "/etc/a*.conf"
#if 0
static int errfunc_(const char *errpath,int eerrno)
{
puts(errpath);
fprintf(stderr,"ERROR MSG:%s\n",strerror(eerrno));
return 0;
}
#endif
int main()
{
glob_t globres;
int err,i;
err=glob(PAT,0,NULL,&globres);
if(err)
{
printf("Error code=%d\n",err);
exit(1);
}
for(i=0;i<globres.gl_pathc;i++)
{
puts(globres.gl_pathv[i]);
}
globfree(&globres)
exit(0);
}
如果要解析/etc下面的所有文件,可以将PAT换成"/etc/*"
如果还要看到隐藏的文件,将PAT换成"etc/.*"
opendir()
----------------------------- open a directory
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
DIR *fdopendir(int fd);
返回值:
The opendir() and fdopendir() functions return a pointer to the direc‐
tory stream. On error, NULL is returned, and errno is set appropri‐
ately.
closedir()
------- close a directory
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
readdir(), readdir_r()
----------------- read a directory
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
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 */
};
用readdir来读取一个打开的目录流,返回值是在这个目录流当中读到的一行内容,这一行内容是这个目录下的文件的基本属性
例子:
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#define PAT "/etc"
int main()
{
DIR * dp;
struct dirent *cur;
dp=opendir(PAT);
if(dp==NULL)
{
perror("opendir()");
exit(1);
}
while((cur=readdir(dp))!=NULL)
{
puts(cur->d_name);
}
closedir(dp);
exit(0);
}