首页 > 其他分享 >文件系统

文件系统

时间:2023-06-16 21:11:06浏览次数:30  
标签:文件 int 文件系统 st 描述符 fd include

用户态和内核态

运行在内核态的进程可以毫无限制的访问各种资源,而在用户态下的用户进程的各种操作都有着限制,比如不能随意的访问内存、不能开闭中断以及切换运行的特权级别。

操作系统一般是通过软件中断从用户态切换到内核态。

函数工作流程

虚拟地址空间

每个进程都会分配虚拟地址空间,在32位机器上,该地址空间为4G。

当应用程序使用虚拟地址访问内存时,处理器(CPU)会将其转化成物理地址(MMU)。MMU:将虚拟的地址转化为物理地址。

文件描述符

//这三个默认打开,所以后面的文件描述符从3开始
#define STDIN_FILENO  0 //标准输入的文件描述符
#define STDOUT_FILENO 1 //标准输出的文件描述符
#define STDERR_FILENO 2 //标准错误的文件描述符

在程序运行起来后打开其他文件时,系统会返回文件描述符表中最小可用的文件描述符,并将此文件描述符记录在表中。

Linux 中一个进程最多只能打开 NR_OPEN_DEFAULT (即1024)个文件,故当文件不再使用时应及时调用 close() 函数关闭文件。

文件io函数

open()
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
​
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
功能:
    打开文件,如果文件不存在则可以选择创建。
参数:
    pathname:文件的路径及文件名
    flags:打开文件的行为标志,必选项 O_RDONLY, O_WRONLY, O_RDWR
    mode:这个参数,只有在文件不存在时有效,指新建文件时指定文件的权限
返回值:
    成功:成功返回打开的文件描述符
    失败:-1
O_RDONLY 以只读的方式打开
O_WRONLY 以只写的方式打开
O_RDWR 以可读、可写的方式打开

可选项,和必选项按位或起来

取值 含义
O_CREAT 文件不存在则创建文件,使用此选项时需使用mode说明文件的权限
O_EXCL 如果同时指定了O_CREAT,且文件已经存在,则出错
O_TRUNC 如果文件存在,则清空文件内容
O_APPEND 写文件时,数据添加到文件末尾
O_NONBLOCK 对于设备文件, 以O_NONBLOCK方式打开可以做非阻塞I/O
write()
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
功能:
    把指定数目的数据写到文件(fd)
参数:
    fd :  文件描述符
    buf : 数据首地址
    count : 写入数据的长度(字节)
返回值:
    成功:实际写入数据的字节个数
    失败: - 1
read()

#include <unistd.h>
​
ssize_t read(int fd, void *buf, size_t count);
功能:
    把指定数目的数据读到内存(缓冲区)
参数:
    fd : 文件描述符
    buf : 内存首地址
    count : 读取的字节个数
返回值:
    成功:实际读取到的字节个数
    失败: - 1
阻塞与非阻塞

阻塞与非阻塞是对于文件而言的,而不是指read、write等的属性。

非阻塞读取一个文件时:如果为非阻塞,但是没有数据可读,此时全局变量 errno 被设置为 EAGAIN

lseek()

#include <sys/types.h>
#include <unistd.h>
​
off_t lseek(int fd, off_t offset, int whence);
功能:
    改变文件的偏移量
参数:
    fd:文件描述符
    offset:根据whence来移动的位移数(偏移量),可以是正数,也可以负数,如果正数,则相对于whence往右移动,如果是负数,则相对于whence往左移动。如果向前移动的字节数超过了文件开头则出错返回,如果向后移动的字节数超过了文件末尾,再次写入时将增大文件尺寸。
​
    whence:其取值如下:
        SEEK_SET:从文件开头移动offset个字节
        SEEK_CUR:从当前位置移动offset个字节
        SEEK_END:从文件末尾移动offset个字节
返回值:
    若lseek成功执行, 则返回新的偏移量
    如果失败, 返回-1
stat()
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
​
int stat(const char *path, struct stat *buf);
int lstat(const char *pathname, struct stat *buf);
功能:
    获取文件状态信息
    stat和lstat的区别:
        当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;
        而stat返回的是该链接指向的文件的信息。
参数:
    path:文件名
    buf:保存文件信息的结构体
返回值:
    成功: 0
    失败: -1
struct stat结构体
struct stat {
    dev_t           st_dev;     //文件的设备编号
    ino_t           st_ino;     //节点
    mode_t          st_mode;            //文件的类型和存取的权限
    nlink_t         st_nlink;       //连到该文件的硬连接数目,刚建立的文件值为1
    uid_t           st_uid;     //用户ID
    gid_t           st_gid;     //组ID
    dev_t           st_rdev;        //(设备类型)若此文件为设备文件,则为其设备编号
    off_t           st_size;        //文件字节数(文件大小)
    blksize_t       st_blksize;     //块大小(文件系统的I/O 缓冲区大小)
    blkcnt_t        st_blocks;      //块数
    time_t          st_atime;       //最后一次访问时间
    time_t          st_mtime;       //最后一次修改时间
    time_t          st_ctime;       //最后一次改变时间(指属性)
};
chmod()

#include <sys/stat.h>
​
int chmod(const char *pathname, mode_t mode);
功能:修改文件权限
参数:
    filename:文件名
    mode:权限(8进制数)
返回值:
    成功:0
    失败:-1
chown()

#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

文件描述符复制

dup() 和 dup2()都是用来复制一个文件的描述符,使新的文件描述符也标识旧的文件描述符所标识的文件。

dup()
#include <unistd.h>
​
int dup(int oldfd);
功能:
    通过 oldfd 复制出一个新的文件描述符,新的文件描述符是调用进程文件描述符表中最小可用的文件描述符,最终 oldfd 和新的文件描述符都指向同一个文件。
参数:
    oldfd : 需要复制的文件描述符 oldfd
返回值:
        成功:新文件描述符
        失败: -1
dup2()
#include <unistd.h>
​
int dup2(int oldfd, int newfd);
功能:
    通过 oldfd 复制出一个新的文件描述符 newfd,如果成功,newfd 和函数返回值是同一个返回值,最终 oldfd 和新的文件描述符 newfd 都指向同一个文件。
参数:
    oldfd : 需要复制的文件描述符
    newfd : 新的文件描述符,这个描述符可以人为指定一个合法数字(0 - 1023),如果指定的数字已经被占用(和某个文件有关联),此函数会自动关闭 close() 断开这个数字和某个文件的关联,再来使用这个合法数字。
返回值:
    成功:返回 newfd
    失败:返回 -1
fcntl()
#include <unistd.h>
#include <fcntl.h>
​
int fcntl(int fd, int cmd, ... /* arg */);
功能:改变已打开的文件性质,fcntl针对描述符提供控制。
参数:
    fd:操作的文件描述符
    cmd:操作方式
    arg:针对cmd的值,fcntl能够接受第三个参数int arg。
返回值:
    成功:返回某个其他值
    失败:-1
fcntl函数有5种功能:

1) 复制一个现有的描述符(cmd=F_DUPFD)

2) 获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD)

3) 获得/设置文件状态标记(cmd=F_GETFL或F_SETFL)

4) 获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN)

5) 获得/设置记录锁(cmd=F_GETLK, F_SETLK或F_SETLKW)
fcntl()将描述符fd设为非阻塞
  int flags=fcntl(fd,F_GETFL);//获取状态
  flags|=O_NONBLOCK;
  fcntl(fd,F_SETFL,flags);
 fcntl(fd, F_SETFL, O_NONBLOCK );

标签:文件,int,文件系统,st,描述符,fd,include
From: https://www.cnblogs.com/persistencejunjie/p/17486509.html

相关文章

  • 虚拟文件系统
    虚拟文件系统虚拟文件系统是负责组织和管理文件系统的,就像虚拟内存用来实现管理内存系统.而在计算机中因为存储介质的问题,所以通常存在多个文件系统.比如:硬盘,光盘,闪盘这些存储介质的不同,还有例如一些操作系统的不同,以及文件特性的不同,因此不同的文件系统在实现上会有所......
  • 关于xfs文件系统uuid的修改方法
    场景1:系统中有两个文件系统的uuid是一样(UUID 是通用唯一识别码(UniversallyUniqueIdentifier)的缩写)场景2:因一些特殊的原因,需要将文件系统的uuid修改成特定的uuid 当然场景1,其实也可以通过笔者另一篇文章中讲到的使用 mount-onouuid/dev/nvme1n1/nvme1n1的方式解......
  • 关于xfs文件系统-在操作系统中遇到两个uuid一样的-挂载报错-wrong fs type, bad optio
    当操作系统中,出现了两个uuid一样的文件系统(笔者这里是xfs),那么默认就只能挂载成功一个[root@qq-5201351~]#blkid|grepxfs|grep1ea9e784-0692-403c-bed1-bf34a5a86a57/dev/nvme1n1:UUID="1ea9e784-0692-403c-bed1-bf34a5a86a57"BLOCK_SIZE="512"TYPE="xfs"/dev/nvme2......
  • 关于磁盘与分区-创建xfs文件系统时指定UUID的方法
    关于在linux系统中对于xfs文件系统创建后,可以通过指定文件系统uuid的方式进行挂载[root@qq-5201351~]#mount-U5a85ee6b-2866-4832-8fea-475d7c8b561c/data01[root@qq-5201351~]#mount-txfs-U5a85ee6b-2866-4832-8fea-475d7c8b561c/data02[root@qq-5201351~]#mou......
  • Network File System 网络文件系统(centos 6)
    预备知识:1 什么是程序、进程、线程?程序:安装的软件就是程序进程:运行的程序---就是进程线程:运行的程序同时完成多个任务2 NFS三个主要组件?Rpc.nfsd  :它是基本的NFS守护进程,主要功能是管理客户端是否能够登录服务器;(由nfs进程实现)Rpc.mount:主要功能是管理NFS......
  • 关于mkfs.xfs创建xfs文件系统指定block-size为512字节时报错-Minimum block size for
    今天笔者看到mkfs.xfs命令的帮助文档手册时,有如下一段内容可以通过-bsize=value的方式指定block的大小,默认值是4096bytes,最小为512,最大为65536Thedefaultvalueis4096bytes(4KiB),  theminimumis512,andthemaximumis65536(64KiB).于是笔者就尝试,创建x......
  • 关于Linux系统中xfs文件系统的创建方法及过程
    XFS一种高性能的日志文件系统,最早于1993年,由SiliconGraphics为他们的IRIX操作系统而开发,是IRIX5.3版的默认文件系统。2000年5月,SiliconGraphics以GNU通用公共许可证发布这套系统的源代码,之后被移植到Linux内核上。XFS特别擅长处理大文件,同时提供平滑的数据传输。XFS最初是......
  • vdbench-磁盘/文件系统性能测试工具
    vdbench是一个I/O测试工具,可以用来测试磁盘和文件系统读写性能centos7安装1、java环境[root@node1~]#yuminstall-yjava-1.8.0-openjdkjava-1.8.0-openjdk-develunzip[root@node1~]#java-versionopenjdkversion"1.8.0_292"OpenJDKRuntimeEnvironment(build......
  • 文件系统
    文件系统文件是面向OS和面向使用者而言的,对于人来说,音乐,图片,文档,游戏,软件,邮件,等记录信息的载体都被操作系统统称为文件,而存储在HDD(机械硬盘)和SSD(固态硬盘)里.因此文件是一种实体的抽象,而之所以文件需要文件名,是因为不同的文件需要进行相对应的区分,也就是文件名,......
  • 文件系统考古2:1984 - BSD Fast Filing System
    今天继续与大家分享系列文章《50yearsinfilesystems》,由KRISTIANKÖHNTOPP撰写。我们将进入文件系统的第二个十年,即1984年,计算机由微型计算机发展到了桌面和机柜工作站,BSDFastFilingSystem登场。回看第一篇:1974-UnixV7FileSystem早期的Unix文件系统已经表现得......