文章目录

  • 前言
  • 一、C标准函数与系统函数的区别
    • 1、什么是系统调用
    • 2、文件描述符
    • 3、相关函数
      • 3.1 open函数
      • 3.2 close函数
      • 3.3 read函数
      • 3.4 write函数
      • 3.5 lseek函数
    • 4、perror和errno
  • 二、阻塞与非阻塞
  • 三、文件和目录
    • 1、文件相关函数
      • 1.1、stat/lstat函数
    • 2、目录相关函数
      • 2.1、opendir函数
      • 2.2、readdir函数
      • 3.3、closedir函数
      • 3.4、dup函数
      • 3.5、dup2函数
      • 3.6、fcntl函数

前言

本文用于记录linux系统函数学习

一、C标准函数与系统函数的区别

1、什么是系统调用

系统调用是由操作系统实现并提供给外部应用程序的编程接口,是应用程序同系统之间数据交互的桥梁。
一个hello world如何打印到屏幕上?

每一个FILE文件流(标准C库函数)都有一个缓冲区buffer,默认大小8192Byte。Linux系统的IO函数默认是没有用户级缓冲区的。

2、文件描述符

一个进程启动之后,默认打开三个文件描述符:

#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2

新打开文件返回文件描述符表中未使用的最小文件描述符,调用open函数就可以打开或创建一个文件,得到一个文件描述符。

3、相关函数

3.1 open函数

函数作用:打开或者新建一个文件

函数原型:
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
函数参数:
pathname参数是要打开或创建的文件名,和fopen一样, pathname既可以是相对路径也可以是绝对路径。
flags参数有一系列常数值可供选择, 可以同时选择多个常数用按位或运算符连接起来, 所以这些常数的宏定义都以O_开头,表示or。必选项:以下三个常数中必须指定一个, 且仅允许指定一个。O_RDONLY 只读打开O_WRONLY 只写打开O_RDWR 可读可写打开以下可选项可以同时指定0个或多个, 和必选项按位或起来作为flags参数。可选项有很多, 这里只介绍几个常用选项:O_APPEND 表示追加。如果文件已有内容, 这次打开文件所写的数据附加到文件的末尾而不覆盖原来的内容。O_CREAT 若此文件不存在则创建它。使用此选项时需要提供第三个参数mode, 表示该文件的访问权限。文件最终权限:mode & ~umaskO_EXCL 如果同时指定了O_CREAT,并且文件已存在,则出错返回。O_TRUNC 如果文件已存在, 将其长度截断为为0字节。O_NONBLOCK 对于设备文件, 以O_NONBLOCK方式打开可以做非阻塞           I/O(NonblockI/O),非阻塞I/O。
函数返回值:成功: 返回一个最小且未被占用的文件描述符失败: 返回-1, 并设置errno值.

3.2 close函数

函数作用:关闭文件

函数原型:int close(int fd);
函数参数:fd文件描述符
函数返回值:成功:返回0失败:返回-1,并设置errno值

需要说明的是,当一个进程终止时, 内核对该进程所有尚未关闭的文件描述符调用close关闭,所以即使用户程序不调用close, 在终止时内核也会自动关闭它打开的所有文件。但是对于一个长年累月运行的程序(比如网络服务器), 打开的文件描述符一定要记得关闭, 否则随着打开的文件越来越多, 会占用大量文件描述符和系统资源。

3.3 read函数

函数作用:从打开的设备或文件中读取数据

函数原型:ssize_t read(int fd, void *buf, size_t count);
函数参数:fd: 文件描述符buf: 读上来的数据保存在缓冲区buf中count: buf缓冲区存放的最大字节数
函数返回值:>0 : 读取到的字节数=0 :文件读取完毕-1 : 出错,并设置errno

3.4 write函数

函数作用:向打开的设备或文件中写数据

函数原型:ssize_t write(int fd, const void *buf, size_t count);
函数参数:fd: 文件描述符buf: 缓冲区,要写入文件或设备的数据count:buf中的数据长度
函数返回值:成功: 返回写入的字节数错误: 返回-1并设置error

3.5 lseek函数

所有打开的文件都有一个当前文件偏移量(current file offset),以下简称为cfo. cfo通常是一个非负整数, 用于表明文件开始处到文件当前位置的字节数. 读写操作通常开始于 cfo, 并且使 cfo 增大, 增量为读写的字节数. 文件被打开时, cfo 会被初始化为 0, 除非使用了 O_APPEND.使用 lseek 函数可以改变文件的 cfo.

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
函数描述: 移动文件指针
函数原型: off_t lseek(int fd, off_t offset, int whence);
函数参数:fd:文件描述符参数 offset 的含义取决于参数 whence:如果 whence 是 SEEK_SET,文件偏移量将设置为 offset。如果 whence 是 SEEK_CUR,文件偏移量将被设置为 cfo 加上 offset,offset 可以为正也可以为负。如果 whence 是 SEEK_END,文件偏移量将被设置为文件长度加上 offset,offset 可以为正也可以为负。
函数返回值: 若lseek成功执行, 则返回新的偏移量。lseek函数常用操作
文件指针移动到头部
lseek(fd, 0, SEEK_SET);获取文件指针当前位置
int len = lseek(fd, 0, SEEK_CUR);获取文件长度
int len = lseek(fd, 0, SEEK_END);lseek实现文件拓展
off_t currpos;
// 从文件尾部开始向后拓展1000个字节
currpos = lseek(fd, 1000, SEEK_END);
// 额外执行一次写操作,否则文件无法完成拓展
write(fd, “a”, 1);  // 数据随便写

4、perror和errno

errno是一个全局变量, 当系统调用后若出错会将errno进行设置, perror可以将errno对应的描述信息打印出来.
如:perror(“open”); 如果报错的话打印: open:(空格)错误信息

二、阻塞与非阻塞

阻塞和非阻塞时文件本身的属性,不是read函数的属性。

  • 普通文件:hello.c 默认是非阻塞的
  • 终端设备:如/dev/tty 默认是阻塞的
  • 管道和套接字:默认是阻塞的

三、文件和目录

1、文件相关函数

1.1、stat/lstat函数

函数作用:获取文件属性

函数原型:int stat(const char *pathname, struct stat *buf);int lstat(const char *pathname, struct stat *buf);
函数返回值:成功返回0失败返回-1struct stat {dev_t          st_dev;        //文件的设备编号ino_t           st_ino;        //节点mode_t         st_mode;      //文件的类型和存取的权限nlink_t         st_nlink;     //连到该文件的硬连接数目,刚建立的文件值为1uid_t           st_uid;       //用户IDgid_t           st_gid;       //组IDdev_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;     //最后一次改变时间(指属性)};- st_mode -- 16位整数0-2 bit -- 其他人权限S_IROTH      00004  读权限S_IWOTH     00002  写权限S_IXOTH      00001  执行权限S_IRWXO     00007  掩码, 过滤 st_mode中除其他人权限以外的信息3-5 bit -- 所属组权限S_IRGRP     00040  读权限S_IWGRP    00020  写权限S_IXGRP     00010   执行权限S_IRWXG    00070  掩码, 过滤 st_mode中除所属组权限以外的信息6-8 bit -- 文件所有者权限S_IRUSR    00400    读权限S_IWUSR   00200    写权限S_IXUSR    00100     执行权限S_IRWXU   00700    掩码, 过滤 st_mode中除文件所有者权限以外的信息If (st_mode & S_IRUSR)   -----为真表明可读If (st_mode & S_IWUSR)  ------为真表明可写If (st_mode & S_IXUSR)   ------为真表明可执行○ 12-15 bit -- 文件类型S_IFSOCK         0140000 套接字S_IFLNK          0120000 符号链接(软链接)S_IFREG          0100000 普通文件S_IFBLK           0060000 块设备S_IFDIR           0040000 目录S_IFCHR           0020000 字符设备S_IFIFO           0010000 管道S_IFMT 0170000 掩码,过滤 st_mode中除文件类型以外的信息if ((st_mode & S_IFMT)==S_IFREG) ----为真普通文件
if(S_ISREG(st_mode))   ------为真表示普通文件
if(S_ISDIR(st.st_mode))  ------为真表示目录文件

stat函数和lstat函数的区别

  • 对于普通文件,这两个函数没有区别,是一样的
  • 对于链接文件,调用lstat函数获取的是链接文件本身的属性信息;而stat函数获取的是链接文件指向的文件的属性信息

2、目录相关函数

2.1、opendir函数

函数作用:打开一个目录

函数原型:DIR *opendir(const char *name);
函数返回值:指向目录的指针
函数参数:要遍历的目录(相对路径或者绝对路径)

2.2、readdir函数

函数作用:读取目录内容——目录项

函数原型:struct *readdir(DIR *dirp);
函数返回值:读取的目录项指针
函数参数: opendir函数的返回值struct dirent{ino_t d_ino;             // 此目录进入点的inodeoff_t d_off;              // 目录文件开头至此目录进入点的位移signed short int d_reclen;   // d_name 的长度, 不包含NULL 字符unsigned char d_type;     // d_name 所指的文件类型 char d_name[256];       // 文件名};d_type的取值: DT_BLK - 块设备DT_CHR - 字符设备DT_DIR - 目录DT_LNK - 软连接DT_FIFO - 管道DT_REG - 普通文件DT_SOCK - 套接字DT_UNKNOWN - 未知

3.3、closedir函数

函数作用:关闭目录

函数原型:int closedir(DIR *dirp);
函数返回值:成功返回0 失败返回-1
函数参数:opendir函数的返回值

读取目录内容的一般步骤

1 DIR *pDir = opendir(“dir”);   //打开目录
2 while((p=readdir(pDir))!=NULL){}  //循环读取文件
3 closedir(pDir);  //关闭目录

3.4、dup函数

函数作用:复制文件描述符

函数原型:int dup(int oldfd);
函数参数:oldfd —— 要复制的文件描述符
函数返回值:成功: 返回最小且没被占用的文件描述符失败:返回-1,设置errno值

3.5、dup2函数

函数作用:复制文件描述符

函数原型:int dup2(int oldfd, int new fd);
函数参数:old——原来的文件描述符newfd——复制成新的文件描述符
函数返回值:成功:将oldfd复制给newfd,两个文件描述符指向同一个文件失败:返回-1,设置error值假设newfd已经指向了一个文件,首先close原来打开的文件,然后newfd指向oldfd指向的文件
若newfd没有被占用,newfd指向oldfd指向的文件

3.6、fcntl函数

函数作用:改变已经打开的文件属性

函数原型: int fcntl(int fd, int cmd, ... /* arg */ );若cmd为F_DUPFD, 复制文件描述符, 与dup相同若cmd为F_GETFL, 获取文件描述符的flag属性值若cmd为 F_SETFL, 设置文件描述符的flag属性
函数返回值:返回值取决于cmd成功若cmd为F_DUPFD, 返回一个新的文件描述符若cmd为F_GETFL, 返回文件描述符的flags值若cmd为 F_SETFL, 返回0失败返回-1, 并设置errno值.fcntl函数常用的操作:1 复制一个新的文件描述符:int newfd = fcntl(fd, F_DUPFD, 0);2 获取文件的属性标志int flag = fcntl(fd, F_GETFL, 0)3 设置文件状态标志flag = flag | O_APPEND;fcntl(fd, F_SETFL, flag)4 常用的属性标志O_APPEND-----设置文件打开为末尾添加O_NONBLOCK-----设置打开的文件描述符为非阻塞

Linux系统编程1——系统函数相关推荐

  1. 【Linux系统编程】vfork() 函数详解

    00. 目录 文章目录 00. 目录 01. vfork函数 02. fork和vfork区别 03. 父子进程地址空间 04. 附录 01. vfork函数 函数分析 #include <sy ...

  2. 【Linux系统编程】fork()函数详解

    00. 目录 文章目录 00. 目录 01. 进程创建函数 02. 父子进程结构 03. 父子进程地址空间 04. 附录 01. 进程创建函数 #include <sys/types.h> ...

  3. Linux系统编程:fork函数的使用【循环创建N个子线程】

    fork函数介绍 在linux下面进行系统编程,一定要养成一个好习惯,不懂的函数 直接 找男人,用man 指令进行查看,虽然是全英文 但是要强迫自己 学会看英文文档!下面是介绍,我们看重点. FORK ...

  4. 【Linux系统编程】fork() 函数详解

    需要的头文件: #include <sys/types.h> #include <unistd.h> pid_t fork(void); 功能: 用于从一个已存在的进程中创建一 ...

  5. linux系统编程:系统函数system

    system函数 该函数是标准库中的函数,头文件为#include <stdlib>,本质上是shell中执行命令/程序. 我们编写代码如下: #include <iostream& ...

  6. Linux系统编程 46 -lseek函数

    学习笔记 lseek函数 文件偏移 以前有接触到fseek 库函数,lseek和它有点类似. #include <sys/types.h> #include <unistd.h> ...

  7. linux系统编程:暂停函数pause

    pause函数 该函数功能主要是暂停进程,它的返回值总是-1. 使用方式: (1)首先使用signal函数提前注册一个中断函数,该函数用于将函数指针和信号做一个绑定; (2)当程序进行执行pause, ...

  8. Linux系统编程—进程—system函数

    system函数 system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程.在调用sys ...

  9. Linux系统编程—文件—write函数

    一.write函数手册上的定义 write函数需要包含头文件 #include <unistd.h> 函数原型:ssize_t write(int fd, const void *buf, ...

最新文章

  1. Cnnot find System Java Compiler Ensure that you have installed a JDK
  2. 如何让gridview中的checkbox根据数据库情况默认选中?
  3. 工厂方法源码解析(jdk+logback)
  4. 简历python技能怎么写_简历怎么写?列出这10项重要的工作技能
  5. ❤️开发项目必备技能《Git用法集合》建议收藏❤️
  6. 微信电脑版重大更新,可以上班刷朋友圈摸鱼了
  7. node文件服务器,nodejs一个简单的文件服务器的创建方法
  8. 最新小说免费API--书香楼,每日不断更新
  9. 宁海象山H5棋牌游戏定制开发
  10. 受美国法律保护美国妞_为什么美国法律有效地要求所有软件设计都要响应
  11. Linux发行版幽灵漏洞的backport
  12. 微信小程序 某个页面直接返回首页(微信小程序回退到首页)
  13. Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能
  14. 工作2年的java程序员怎么提高技术?
  15. Nginx 配置 SSL 证书 + HTTPS 站点小记
  16. linux指令速查手册 中文高清pdf版,linux指令速查手册
  17. python网页制作web_使用python创建web静态网站
  18. 【高等代数】第一章:多项式部分【2】
  19. 上线一套 BI 系统真的很贵?
  20. APP适配IOS8,iPhone6和Plus截图简要说明

热门文章

  1. 中国企业入局AR芯片市场,提升元宇宙时代的核心竞争力
  2. vue Element
  3. 幼儿教师个人简历模板范文
  4. 2011 Heilongjiang collegiate programming contest 【(7+1)/10】 [补完]
  5. (一)软件开发流程与图
  6. 手机系统应用STK 问题总结
  7. 我的前端之路 (css篇)
  8. 我眼中的王石(转 目光呆滞的润土)
  9. 中台详解(下)——怎么搭建中台
  10. 保险公司需要中台吗?