Linux系统调用与文件操作详解

系统调用:

是用户访问内核的唯一方式(因为能直接调用内核的话就没用安全性,而内核中设置的大量函数其实想被用户所调用,就来了个中间人系统调用通过媒介来传话给内核从而调用)



而像我们使用的window系统 eg.window系统鼠标的右键来进行一个新建的文件写入和关闭等等....

在我们的linux系统当中呢,linux下提供的API(应用程序编程接口)(函数)来进行一些操作,create,open,close,write,一些操作

我们要知道一些基础的linux常见的处理目录的一些命令

  • ls(英文全拼:list files): 列出目录及文件名
  • cd(英文全拼:change directory):切换目录
  • pwd(英文全拼:print work directory):显示目前的目录
  • mkdir(英文全拼:make directory):创建一个新的目录
  • rmdir(英文全拼:remove directory):删除一个空的目录
  • cp(英文全拼:copy file): 复制文件或目录
  • rm(英文全拼:remove): 删除文件或目录
  • mv(英文全拼:move file): 移动文件与目录,或修改文件与目录的名称

在应用层每当打开或者写入都会使内核运转,产生一个结构体里面包括大小,等等同时返回一个,非负整数也就是文件描述符,我们通常用变量fd来存储,无论是使用写入,关闭也要用到文件描述符fd,eg int fd = open(/temp ,O_RDONLY)

在上面看来我们第二个参数就是我们权限啦

基础的权限旗标,flag

参数 pathname 指向欲打开的文件路径字符串. 下列是参数flags 所能使用的旗标:
O_RDONLY 以只读方式打开文件
O_WRONLY 以只写方式打开文件
O_RDWR 以可读写方式打开文件. 上述三种旗标是互斥的, 也就是不可同时使用, 但可与下列的旗标利用OR(|)运算符组合.
O_CREAT 若欲打开的文件不存在则自动建立该文件.
O_EXCL 如果O_CREAT 也被设置, 此指令会去检查文件是否存在. 文件若不存在则建立该文件, 否则将导致打开文件错误. 此外, 若O_CREAT 与O_EXCL 同时设置, 并且欲打开的文件为符号连接, 则会打开文件失败.
O_NOCTTY 如果欲打开的文件为终端机设备时, 则不会将该终端机当成进程控制终端机.
O_TRUNC 若文件存在并且以可写的方式打开时, 此旗标会令文件长度清为0, 而原来存于该文件的资料也会消失.
O_APPEND 当读写文件时会从文件尾开始移动, 也就是所写入的数据会以附加的方式加入到文件后面.
O_NONBLOCK 以不可阻断的方式打开文件, 也就是无论有无数据读取或等待, 都会立即返回进程之中.
O_NDELAY 同O_NONBLOCK.
O_SYNC 以同步的方式打开文件.
O_NOFOLLOW 如果参数pathname 所指的文件为一符号连接, 则会令打开文件失败.
O_DIRECTORY 如果参数pathname 所指的文件并非为一目录, 则会令打开文件失败

基础函数

fcntl函数

fcntl 是一个用于操作文件描述符的系统调用函数。它可以执行多种操作,如复制文件描述符、获取和设置文件描述符标志、文件状态标志以及记录锁等


先看**int fcntl(int fd, int cmd, ... /* arg */);**参数第一个是文件描述符,来追踪文件,第二个是文件的指令,比如读写,第三个可选的参数,如果用一个新的变量来接收,fcntl函数,这样就能大致理解,函数的作用了吧,能够复制或则和设置,获取文件描述符,多系列的操作.

一些基础fcntl基础指令旗标flag

  • F_DUPFD : 复制文件描述符 fd,返回新的文件描述符。

  • F_DUPFD_CLOEXEC : 类似于 F_DUPFD ,但会设置 FD_CLOEXEC 标志,表示在执行 exec 系列函数后,该描述符会关闭。

  • 获取/设置文件描述符标志

  • F_GETFD: 获取文件描述符标志。

  • F_SETFD: 设置文件描述符标志。

  • 获取/设置文件状态标志

  • F_GETFL: 获取文件状态标志。

  • F_SETFL: 设置文件状态标志。

  • 获取/设置记录锁

  • F_GETLK: 获取记录锁。

  • F_SETLK: 设置记录锁。

  • F_SETLKW: 设置记录锁并等待。

open函数

基本定义: 是 C 语言中用于打开或创建文件的系统调用,定义在 <fcntl.h> 头文件中。它返回一个文件描述符,用于后续的文件操作。

头文件:#include <unistd.h>

定义函数:

int open(const char * pathname, int flags);

eg:打开文件并且写入

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>

int main() {

int fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);//这个第三个参

//就是模式和权限

if (fd == -1) {

perror("Error opening file");

return -1;

}

write(fd, "Hello, World!", 13);

close(fd);

return 0;

}

write函数

基本定义: 是 C 语言中用于将数据写入文件的系统调用。它通过文件描述符将缓冲区中的数据写入到指定的文件中,同时会更新文件的读写位置。

头文件:#include <unistd.h>

函数定义

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);

  • fd: 文件描述符,表示目标文件。

  • buf: 指向要写入数据的缓冲区。

  • count: 要写入的字节数。

  • eg// write 函数将字符串写入文件,并读取文件内容进行验证:

  • #include <stdio.h>

    #include <fcntl.h>

    #include <unistd.h>

    #include <string.h>

    int main() {

    int fd;

    char buf[] = "Hello, World!";

    char read_buf[32] = {0};

    // 打开文件(如果不存在则创建)

    fd = open("example.txt", O_RDWR | O_CREAT | O_TRUNC, 0666);

    if (fd < 0) {

    perror("open");

    return 1;

    }

    // 写入数据

    ssize_t written = write(fd, buf, strlen(buf));

    if (written < 0) {

    perror("write");

    close(fd);

    return 1;

    }

    printf("Written %ld bytes: %s\n", written, buf);

    // 重置文件指针到开头

    lseek(fd, 0, SEEK_SET);

    // 读取数据

    ssize_t read_bytes = read(fd, read_buf, sizeof(read_buf) - 1);

    if (read_bytes < 0) {

    perror("read");

    close(fd);

    return 1;

    }

    printf("Read %ld bytes: %s\n", read_bytes, read_buf);

    // 关闭文件

    close(fd);

    return 0;

    }

read函数

**函数定义:**用于从文件或设备中读取数据。它是低级别 I/O 操作的核心,直接与内核交互。

头文件:#include <unistd.h>
定义函数:ssize_t read(int fd, void * buf, size_t count);

  • fd : 文件描述符,通过 open 获取。

  • buf: 指向用户分配的缓冲区,用于存储读取的数据。

  • count: 要读取的最大字节数。

  • eg//以下是一个简单示例,展示如何使用 read 从文件中读取数据:

  • #include <stdio.h>

    #include <fcntl.h>

    #include <unistd.h>

    int main() {

    int fd;

    ssize_t bytesRead;

    char buffer[1024]; // 定义缓冲区

    // 打开文件

    fd = open("example.txt", O_RDONLY);

    if (fd == -1) {

    perror("Failed to open file");

    return 1;

    }

    // 读取数据

    bytesRead = read(fd, buffer, sizeof(buffer) - 1);

    if (bytesRead == -1) {

    perror("Failed to read file");

    close(fd);

    return 1;

    }

    // 确保字符串以 '\0' 结束

    buffer[bytesRead] = '\0';

    printf("Read %zd bytes: %s\n", bytesRead, buffer);

    // 关闭文件

    close(fd);

    return 0;

    }

//函数说明:read()会把参数fd 所指的文件传送count 个字节到buf 指针所指的内存中. 若参数count 为0, 则read()不会有作用并返回0. 返回值为实际读取到的字节数, 如果返回0, 表示已到达文件尾或是无可读取的数据,此外文件读写位置会随读取到的字节移动.

谢谢大家的点赞和收藏,博主会坚持更新和学习,接下来会接着发布基础函数和例子来练习和熟悉这些用户与内核的安全桥梁的函数,后面这部分学习完就会发布嵌入式开发路线和学习内容,再次感谢大家的支持和喜欢如果有想要一起学习和讨论的朋友可以加一下QQ群相互学习:238038904

!!!

相关推荐
ZFB00012 小时前
【麒麟桌面系统】V10-SP1 2503 系统知识——常见用户组简介
linux·运维·kylin
acrelgxy2 小时前
告别被动抢修与盲目巡检!安科瑞运维云平台,让电力系统实现预测性守护。
运维·电力监控系统·智能电力仪表
EndingCoder2 小时前
类的继承和多态
linux·运维·前端·javascript·ubuntu·typescript
信创天地3 小时前
深耕金融政务核心场景:国产化数据库迁移的全流程架构设计与风险管控
运维·网络安全·系统架构·系统安全·运维开发
ZFB00013 小时前
【麒麟桌面系统】V10-SP1 2503 系统知识——添加用户
linux·运维·kylin
释怀不想释怀3 小时前
Docker(网络)
运维·docker·容器
ZFB00013 小时前
【麒麟桌面系统】V10-SP1 2503 系统知识——进入救援模式
linux·运维·kylin
RisunJan3 小时前
Linux命令-iptables-restore命令(从文件批量恢复 iptables 防火墙规则)
linux·运维·网络
轻造科技4 小时前
周期压缩极限挑战:APS排产优化这样实现
运维·devops