Linux系统编程-文件系统-1 stat/lstat、truncate、link/unlink、dup/dup2

文件存储

一个文件主要有两部分组成:dentry(目录项)和inode

inode本事是结构体,存储文件的属性信息,如权限、类型、大小、时间、用户、盘块位置......也叫做文件属性管理结构。大多书的inode都存储在磁盘上,少量常用、近期使用的inode会被缓存到内存中。

所谓的删除文件,就是删除inode,但是数据其实还是在硬盘上,当没有inode指向这个盘块以后,这个盘块之后会覆盖掉。

dentry本质也是一个结构体,里面有两个重要的成员是文件名、inode。而文件内容保存在磁盘盘块中。

stat/lstst函数

获取文件属性(从inode结构体中获取)

stat/lstat 函数:

        int stat(const char *path, struct stat *buf);

        #include <sys/types.h>
        #include <sys/stat.h>
        #include <unistd.h>

        参数:
                path: 文件路径

                buf:(传出参数) 存放文件属性。

        返回值:

                成功: 0

                失败: -1 errno

    获取文件大小: buf.st_size

    获取文件类型: buf.st_mode

    获取文件权限: buf.st_mode

    符号穿透:stat会。lstat不会。

stat会拿到符号链接(软链接、硬链接)指向那个文件或目录的属性。不想被穿透的话就用lstat

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
	struct stat buf;

	int ret = stat("temp.txt", &buf);
	if(ret == -1){
		perror("stat error");
		exit(1);
	}

	printf("st_ino = %ld\n", buf.st_ino);
	printf("st_size = %ld\n", buf.st_size);
	printf("st_nlink = %d\n", buf.st_nlink);
	printf("st_uid = %d\n", buf.st_uid);
	printf("st_gid = %d\n", buf.st_gid);
	printf("st_mode = %x\n", buf.st_mode);

	return 0;
}

truncate函数

截断文件长度成指定长度。常用来拓展文件大小,代替lseek。

int truncate(const char *path, off_t length); 成功 0 ;失败 1 设置 errno 为相应值
int ftruncate(int fd, off_t length);

link/unlink函数

硬链接数就是dentry数目

link就是用来创建硬链接数的

link可以用来实现mv命令

函数原型:

                int link(const char *oldpath, const char *newpath)

                #include <fcntl.h>           /* Definition of AT_* constants */
                #include <unistd.h>

                用这个来实现mv,用oldpath来创建newpath,完事儿删除oldpath就行。

删除一个链接:

                int unlink(const char *pathname)
                unlink是删除一个文件的目录项dentry,使硬链接数-1
unlink函数的特征:清除文件时,如果文件的硬链接数到0了,没有dentry对应,但该文件仍不会马上被释放,要等到所有打开文件的进程关闭该文件,系统才会挑时间将该文件释放掉。

隐式回收

当进程结束运行时,所有进程打开的文件会被关闭,申请的内存空间会被释放。系统的这一特性称之为隐式回收系统资源。

要是没有在程序中关闭文件描述符,没有隐式回收的话,这个文件描述符会保留,多次出现这种情况会导致系统文件描述符耗尽。所以隐式回收会在程序结束时收回它打开的文件使用的文件描述符。

dup/dup2函数

用来做重定向,本质是复制文件描述符:

        int dup(int oldfd);        文件描述符复制。 

                oldfd: 已有文件描述符

                返回:新文件描述符。

        int dup2(int oldfd, int newfd); 文件描述符复制。重定向。  new->old   #include <unistd.h>

fcntl 函数实现 dup:

int fcntl(int fd, int cmd, ....)

        cmd: F_DUPFD   

        当 fcntl 的第二个参数为 F _DUPFD 时, 它的作用是根据一个已有的文件描述符,复制
生成一个新的文件描述符。此时, fcntl 相当于 dup 和 dup 2 函数。

        参3:      被占用的,返回最小可用的文件描述符。

        未被占用的, 返回=该值的文件描述符。

目录操作函数

getcwd函数:获取当前进程工作目录(库函数)

char *getcwd(char *buf, size_t 成功: buf 中保存当前进程工作目录位置。失败返回 NULL 。

chdir函数: 改变当前进程的工作目录

int chdir(const char *path); 成功 0 ;失败 1 设置 errno 为相应值

opendir函数: 根据传入的目录名打开一个目录(库函数)

DIR *opendir(const char * name); 成功返回指向该目录结构体指针,失败返回 NULL

closedir函数: 关闭打开的目录

int closedir(DIR *dirp);   成功 0 ;失败 1 设置 errno 为相应值

readdir函数: 读取目录(库函数)

struct dirent *readdir(DIR *dirp); 成功返回 目录项 结构体指针;失败返回 NULL 设置 errno
为相应值

struct dirent {
        i no_t d_ino;   //inode 编号
        off_t d_off;
        unsigned short d_reclen; //文件名有效长度
        unsi gned char d_type; //类型 (vim 打开看到的类似@*/ 等)
        char d_name[256]; //文件名
}
其成员变量重点记忆两个 d_ino 、 d_name 。 实际应用中只使用到 d_name 。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值