1.文件系统

1.1 文件存储

1.1.1 inode

  本质:struct 结构体。存储文件的属性信息。如:权限、类型、大小、时间、用户、盘块位置

  大多数的 inode 保存在磁盘中,少量常用、近期使用的 inode 保存在内存中

1.1.2 dentry 目录项

  本质:struct 结构体 {文件名、inode 号 …} 文件内容保存在盘块中

1.1.3 文件系统

  一组规则,规定对文件的存储及读取的方式、方法。在磁盘格式化时指定。如:fat32、ntfs、ext2/3/4

2.文件操作

2.1 stat 和 lstat

  功能:查看文件信息

1
2
3
4
5
6
7
8
9
10
#include <sys/stst.h>
struct stat statbuf; // 传入&statbuf用于接收文件属性信息
int stat(const char* pathname, struct stat* statbuf); // 会穿透符号链接(软连接)
int lstat(const char* pathname, struct stat* statbuf); // 不会穿透符号链接(软连接)
/*
pathname: 文件名
statbuf: 传出参数,充当返回值,保存文件属性信息

return: 成功0, 失败-1 errno
*/
  • 文件大小:statbuf.st_size
  • 文件类型:statbuf.st_mode

2.2 access

  功能:测试指定文件是否具有某种属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <unistd.h>

int access(const char *pathname, int mode);
/*
pathname:文件名
mode:文件权限,4种权限
R_OK: 是否有读权限
W_OK: 是否有写权限
X_OK: 是否有执行权限
F_OK: 测试文件是否存在

return:
0:有某种权限,或者文件存在
-1:没有,或文件不存在
*/

2.3 chmod

  功能:修改文件权限

1
2
3
4
5
6
7
8
9
10
11
#include <sys/stat.h>

int chmod(const char *pathname, mode_t mode);
/*
参数:
filename:文件名
mode:权限(8进制数)
返回值:
成功:0
失败:-1
*/

2.4 chown

  功能:修改文件所有者和所属组

1
2
3
4
5
6
7
8
9
10
11
12
#include <unistd.h>

int chown(const char *pathname, uid_t owner, gid_t group);
/*
参数:
pathname:文件或目录名
owner:文件所有者id,通过查看 /etc/passwd 得到所有者id
group:文件所属组id,通过查看 /etc/group 得到用户组id
返回值:
成功:0
失败:-1
*/

2.5 truncate

  功能:修改文件大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <unistd.h>
#include <sys/types.h>

int truncate(const char *path, off_t length);
/*
参数:
path:文件文件名字
length:指定的文件大小
a)比原来小, 删掉后边的部分
b)比原来大, 向后拓展
返回值:
成功:0
失败:-1
*/

  功能:创建一个软链接

1
2
3
4
5
6
7
8
9
10
11
#include <unistd.h>

int symlink(const char *target, const char *linkpath);
/*
参数:
target:源文件名字
linkpath:软链接名字
返回值:
成功:0
失败:-1
*/

  功能:创建一个硬链接

1
2
3
4
5
6
7
8
9
10
11
#include <unistd.h>

int link(const char *oldpath, const char *newpath);
/*
参数:
oldpath:源文件名字
newpath:硬链接名字
返回值:
成功:0
失败:-1
*/

  功能:删除一个文件(软硬链接文件)

1
2
3
4
5
6
7
8
9
10
#include <unistd.h>

int unlink(const char *pathname);
/*
参数:
pathname:删除的文件名字
返回值:
成功:0
失败:-1
*/
  • 调用unlink,只是让文件具备了被释放的条件,但不一定被立即释放
  • 硬链接计数为0(没有dentry对应)的文件仍然不会被立刻释放,只有所有打开该文件的进程都结束后,系统才会择机释放该文件

3. 目录操作

3.1 opendir

1
2
3
#include <dirent.h>
DIR* opendir(const char* name);
// 根据相对或绝对路径得到目录指针

3.2 closedir

1
2
3
#include <dirent.h>
int closedir(DIR* dirp);
// 根据给定的目录关闭

3.3 readdir

1
2
3
4
5
6
7
8
9
10
11
#include <dirent.h>
struct dirent* readdir(DIR* dirp);

struct dirent
{
ino_t d_ino; // 此目录进入点的inode
off_t d_off; // 目录文件开头至此目录进入点的位移
signed short int d_reclen; // d_name 的长度, 不包含NULL 字符
unsigned char d_type; // d_type 所指的文件类型
char d_name[256]; // 文件名
};

4.文件描述符复制

4.1 dup

功能:通过 oldfd 复制出一个新的文件描述符,新的文件描述符是调用进程文件描述符表中最小可用的文件描述符,最终 oldfd 和新的文件描述符都指向同一个文件。

1
2
3
4
5
6
7
8
9
10
#include <unistd.h>

int dup(int oldfd);
/*
参数:
oldfd : 需要复制的文件描述符 oldfd
返回值:
成功:新文件描述符
失败: -1
*/

应用举例

1
2
save_fd = dup(STDOUT_FILENO);    // 拿到标准输出的文件描述符
write(save_fd, msg, strlen(msg)); // 数据会被写到屏幕

4.2 dup2

功能:把 参数1 的文件描述符覆盖到 参数2 的文件描述符,效果是 参数1 和 参数2 的文件描述符变成相同的

1
2
3
4
5
6
7
8
9
10
11
#include <unistd.h>

int dup2(int oldfd, int newfd);
/*
参数:
oldfd : 需要复制的文件描述符
newfd : 新的文件描述符,这个描述符可以人为指定一个合法数字(0 - 1023),如果指定的数字已经被占用(和某个文件有关联),此函数会自动关闭 close() 断开这个数字和某个文件的关联,再来使用这个合法数字。
返回值:
成功:返回 newfd
失败:返回 -1
*/

img

4.3 fcntl

1
int n = fcntl(fd, F_DUPFD, 18)

给定一个原先的文件描述符,然后给定一个新的文件描述符,复制进去。如果文件描述符的位置为空可以复制,不为空则分配一个可以分配的最小文件描述符