linux一些API函数

本文详细介绍了文件操作的系统调用,包括open、read、write、fcntl、lseek等函数的使用,以及文件权限、文件描述符、inode和dentry的概念。还讨论了阻塞与非阻塞、硬链接与符号链接、文件重命名及工作目录管理。内容涵盖了文件的创建、打开、读写、定位、属性获取和修改等方面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

open (文件路径, 标志, mode)

返回值: 文件描述符, 如果是正数, 表示打开成功, 否则返回-1

文件操作的主标志.
O_RDONLY 以只读方式,
O_RDWR 以可读可写方式
O_WRONLY 以只写方式

主表示是互斥的, 使用其中的一种不能再使用其另一种

文件操作的副标志:
O_APPEND 读写文件从文件尾部开始移动, 所写入的数据追加到文件尾巴
O_TRUNC 若文件存在且以可写的方式打开时, 此标志会将文件长度清为0,而原来存在的文件的资料也会消失.
O_CREAT 若路径中的文件不存在则自动建立文件
O_EXCL 如果与O_CREAT 同时设置, 此指令会去检查文件是否存在, 文件若不存在则建立该文件, 否则将导致打开文件错误.
.此外, 若O_CREAT与O_EXCL 同时设置, 并且将要打开的文件为符号链接, 则将导致打开文件失败.

文件权限 = mode & ~umask
umask 可以在命令行执行以下, 就可以得到umask
得到umask = 0002, 不用管第一个0 ,表示八进制, 得到文件权限是775
文件权限标志,.
S_IRUSR 所有者拥有读权限 umask 变量表示方法 第一位 4
S_IWUSR 所有者拥有写权限\ umask 变量表示方法 第一位2
S_IXUSR 所有者拥有执行权限 umask 变量表示方法 第一位 1

S_IRGRP 群组拥有读权限 umask 变量表示方法 第二位 4
S_IWGRP 群组拥有写权限 umask 变量表示方法 第二位 2
S_IXGRP 群组拥有执行权限 umask 变量表示方法 第二位 1

S_IROTH 其他用户有读权限 umask 变量表示方法 第三位 4
S_IWOTH 其他用户有写权限 umask 变量表示方法 第三位 2
S_IXOTH 其他用户有执行权限 umask 变量表示方法 第三位 1

close(fd)

read 函数,
ssize_t read(int fd, void *buf, size_t count)
参数: fd: 文件描述符
buf: 存数据的缓冲区
count: 缓冲区大小
返回值: 0, 读到文件末尾
成功; 读到的字节数.
失败, -1, 设置errno
-1; 并且errno = EAGIN 或EWOULDBLOCK, 说明不是read 失败,
而是raad在以非阻塞方式读取一个设备文件(网络文件), 并且文件无数据.

fcntl 改变文件属性
fcntl 用来改变一个(已经打开)的文件,访问控制属性,重点掌握两个参数,
F_GETFL, F_SETFL,
fcntl:
int(int fd, int cmd, …)
fd, 文件描述符
cmd 命令, 决定了后续参数个数
int flgs = fcntl(fd, F_GETFL);
flgs = |= O_NONBLOCK
fcntl(fd, F_SETFL, flgs);

获取文件属性: F_GETFL
设置文件属性 F_SETFL

lseek 函数
off_t lseek(int fd, off_t offset, int whence);

参数: fd: 文件描述符
offset: 偏移量, 就是将读写指针从whence 指定位置向后偏移offset个单位
whence: 起始偏移位置: SEEK_SET/SEEK_CUR/SEEK_END
SEEK_SET 文件起始
SEEK_CUR:表示文件的相对当前位置
SEEK_END 文件末尾

返回值:

	成功:较起始位置偏移量

	失败:-1 errno

应用场景:
1. 文件的“读”、“写”使用同一偏移位置。

	2. 使用lseek获取文件大小
	 lseek(fd, 0, SEEK_END);

	3. 使用lseek拓展文件大小:要想使文件大小真正拓展,必须引起IO操作。
	 lseek(fd, 100, SEEK_END);
	 write(fd, "\0", 1);   // 还要引起IO的操作

		使用 truncate 函数,直接拓展文件。	int ret = truncate("dict.cp", 250);

查看文件内容命令
od -tcx filename 查看文件的16进制表示形式
od-tcd filename 查看文件的10进制表示形式

x 表示的是16进制
d表示的是10进制.

阻塞, 非阻塞
产生阻塞的场景, 读取设备文件, 读取网络文件, (读常规文件,无阻塞概念)
/dev/tty

想要进行非阻塞状态进行读取, 可以在open的时候O_NONBLOCK

一个文件主要由两部分 dentry 目录项, 和inode
inode 本质是结构体, 存储文件属性信息, 如:权限, 类型,大小, 时间, 用户, 盘块位置…
也叫文件属性管理结构, 大多数的inode都存在磁盘上
少量常用,近期使用的inode 会被缓存到内存中
所谓的删除文件, 就是删除inod, 但是数据其实还在硬盘上,以后会被覆盖掉.

dentry: 文件名+inode

stat 函数
获取文件属性(从inode 结构体中获取)
stat/lstat函数
int stat(const char *path, struct stat *buf)
参数:
path: 文件路径
buf:(传出参数) 存放文件属性, inode 结构体指针.
返回值: 成功0, 失败-1, errno
获取文件大小: buf.st_size
获取文件类型: buf.st_mode
获取文件权限: buf.st_mode
符号穿透: stat会, lstat不会

一些宏函数:
st_mode 对于这个文件类型来说, 这些宏函数可以进行判断
S_ISREG (m)
S_ISDIR (m)
S_ISBLK (m)
S_ISLINK(m)

比如我们查看一个链接文件的时候, S_ISLINK(m)
如果是stat 获取得到的 st_mode , 那么看到的是这个符号指向的文件本体,
而不是符号链接,
lstat 则不会, 会显示的是链接文件

但是这些宏函数我在ubuntu18.04当中查找没有找到,
在ubuntu 14.04版本中可以看得到

创建管道文件: mkfifo 文件名.
link和unlink 隐式回收

硬链接就是dentry数目
link就是用来创建硬链接的link可以用来实现mv命令,
函数原型:
int link(const char *oldpath, const char *newpath);
用这个来实现mv,用oldpath来创建newpath, 完事儿删除oldpath就行.

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

想要查看符号链接文件, 不能使用cat 进行查看, 需要readlink 函数查看

rename函数
重命名一个文件
int rename(const char *oldpath, const char *newpath); 成功: 0; 失败, -1 设置errno为相应值

getcwd 获取进程当前工作目录
char *getcwd(char *buf, size_t size); 成功: buf保存当前进程工作目录位置, 失败返回NULL
chdir 函数
改变当前进程的工作目录
int chdir(const char *path) 成功: 0; 失败: -1设置errno为相应值.

目录设置赞粘性, 若有w权限, 创建, 删除 修改, 只能由root 目录所有者, 文件所有者进行从操作.

目录操作的函数:

DIR * opendir(char *name);
int closedir(DIR *dp);
struct dirent *readdir(DIR * dp);

	struct dirent {

		inode

		char dname[256];
	}

没有写目录操作,因为目录写操作就是创建文件。可以用touch

dup 和dup2
用来做重定向, 本质就是复制文件描述符
dup和dup2
int dup(int oldfd); 文件描述符
oldfd: 已有文件描述符
返回: 新文件描述符, 这个描述符和oldfd指向相同内容
int dup2(int oldfd, int newfd); 文件描述符复制, oldfd拷贝给newfd,

fcntl 实现dup 描述符
fcntl 函数实现dup;
int fcntl(int fd, int cmd, …)
fd 文件描述符
cmd F_DUPFD
参数3: 一个数值, 比如是0, 如果0被占用,则返回最小的可用, 没有被占用, 则返回=该文件描述符.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值