总结《Unix/Linux系统编程》中关于使用系统调用进行文件读写的部分
涉及opendir、readdir、readlink、open、close、read、write、lseek系统调用

1. 打开,读取目录文件

目录也是一个文件,但是与普通文件不同,目录文件通过opendirreaddir库函数进行打开与读取

1.1 opendir库函数

根据目录名打开目录文件,返回一个指向该目录流的指针,该流被定位在目录的第一个条目上。目录中的每一个条目都指向该目录中的一个文件,目录中还有两个特殊的目录条目即".“和”.."分别是该目录文件和上一级目录文件。失败返回NULL

DIR *opendir(const char * name)

1.2 readdir库函数

readdir()函数返回一个指向dirent结构的指针,该结构代表了目录流中的下一个目录条目。当到达目录流的末端或发生错误时,返回NULL

struct dirent * readdir(DIR * dirp)

dirent结构体

           struct dirent {ino_t          d_ino;       /* inode number */off_t          d_off;       /* not an offset */unsigned short d_reclen;    /* 该条目长度 */unsigned char  d_type;      /* 文件类型 */char           d_name[256]; /* 文件名,最长255个字符 */};

1.3 目录文件示例

打开目录文件并打印出该目录中所有条目信息

test1.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>int main(){DIR* dir = opendir("/home/xtark/wudi/210525");struct dirent *d;while(d = readdir(dir)){printf("the inode number is : %ld\n",d->d_ino);printf("the d_off is %ld\n",d->d_off);printf("the lengh of this record is %d\n",d->d_reclen);printf("the type of this file is %d\n",d->d_type);printf("the file name is %s\n\n\n",d->d_name);}
}

运行结果:可以看出有两个目录条目分别是".“和”.."分别指向该目录文件与上一级目录文件

xtark@xtark-vmpc:~/桌面/linux_study/section8$ gcc test1.c
xtark@xtark-vmpc:~/桌面/linux_study/section8$ ./a.out
the inode number is : 1045496
the d_off is : 2240378328779100918
the lengh of this record is : 32
the type of this file is : 8
the file name is : test.othe inode number is : 1045454
the d_off is : 2801854051817173045
the lengh of this record is : 24
the type of this file is : 4
the file name is : .the inode number is : 1045439
the d_off is : 2838125603082282148
the lengh of this record is : 24
the type of this file is : 4
the file name is : ..the inode number is : 1045490
the d_off is : 3113460208815849764
the lengh of this record is : 32
the type of this file is : 8
the file name is : test.h

2. 读取软链接文件readlink

Linux中open系统调用遵循符号链接,即如果open一个软链接文件,那么实际打开的是该软链接文件引用的目标文件而非软链接文件本身

如果要打开软链接文件本身,需要使用readlink系统调用

该系统调用根据文件名打开软链接文件本身,并将文件内容复制len个字节到buf中,并返回实际复制字节数

ssize_t readlink(const char * path, char * buf, size_t len)

示例:

创建log.txt及它的软链接文件symlinkFile.txt(退回到上一级目录创建该软链接文件),然后编写test2.c代码

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main(){char buf[1024];int num = readlink("../symlinkFile.txt",buf,sizeof(buf)-1);buf[num] = 0;printf("%s\n",buf);
}

运行结果:可见软链接文件的内容仅仅是其链接的目标文件的路径。这也是为什么读取软链接文件时,系统会自动将访问者导向其指向的目标文件

xtark@xtark-vmpc:~/桌面/linux_study/section8$ gcc test2.c
xtark@xtark-vmpc:~/桌面/linux_study/section8$ ./a.out
section8/log.txt

3. open-close-read-write-lseek系统调用

3.1 close系统调用

close()函数关闭文件描述符(使之成为未使用的文件描述符,后面其他文件可以使用该fd)并释放相应的内核资源,成功返回0,出错返回-1

int close(int fd);

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

3.2 open系统调用

open()函数会打开一个文件,并使用最小的未使用的文件描述符数值作为文件描述符(因此一般是从3开始,然后4,5,6一直下去)成功返回文件描述符,失败返回-1

int open(const char *pathname, int flags,mode_t mode);
  • 参数path是要打开或者要创建的文件路径

  • 参数flags用于指定文件的打开/创建模式,这个参数可由以下常量(定义于 fcntl.h)构成:

    flags必须包含下列访问模式中的一种O_RDONLY(只读)、O_WRONLY(只写)、O_RDWR(读写)

    上述的标志位可以与其他标志进行按位或|组合:O_CREAT(如果文件不存在则创建)、O_APPEND(追加)、O_TRUNC(若文件存在,则长度被截为0)、O_CLOEXEC(在进程执行exec系统调用时关闭此打开的文件描述符)

    除此之外还有很多模式,这里只列举了常用的部分。

  • 第三个参数mode仅当创建新文件时才使用,用于指定文件的访问权限位,如八进制数字如0777,表示文件所有者、该文件用户组、其他用户都有可读可写可执行权限。

3.3 read系统调用

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

第一个参数fd是文件描述符,第二个参数buf是缓存区,第三个参数count是读取字节数。即为从fd代指的文件中读取count个字节到buf缓冲区。

返回读取的字节数,-1表示读取失败,如果在调read之前已到达文件末尾,则这次read返回0。

示例:log.txt文件中有13个字节的内容,main.c文件分三次读取log.txt,每次读取8个字节并打印输出

log.txt

1234567890abc

main.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(){int fd = open("log.txt",O_RDONLY);//打开文件并返回文件描述符char buf[20];           //设置缓存区保存读取到的数据int num = 0;            //记录读取到的字节数num = read(fd,buf,8);   //读取8个字节buf[num] = '\0';        //字符串结尾printf("%d %s\n",num,buf);num = read(fd,buf,8);   //读取8个字节buf[num] = '\0';        //字符串结尾printf("%d %s\n",num,buf);num = read(fd,buf,8);   //读取8个字节buf[num] = '\0';        //字符串结尾printf("%d %s\n",num,buf);
}

运行结果

xtark@xtark-vmpc:~/桌面/linux_study/section3/pip test$ gcc main.c
xtark@xtark-vmpc:~/桌面/linux_study/section3/pip test$ ./a.out
8 12345678
5 90abc
0

可见第一次成功读取了8个字节,第二次虽然想读取8个字节然而只读取了5个字节,第三次由于读写指针指向文件尾,因此读取到了0个字节。

3.4 write系统调用

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

第一个参数fd是文件描述符,第二个参数buf是缓存区,第三个参数count是写入字节数。即将buf中的count字节个数据写入fd代指的文件中。

返回写入的字节数,-1表示写入失败

3.5 lseek系统调用

该系统调用用于改变文件读写指针位置。将文件读写指针相对whence移动offset个字节

__off_t lseek(int fd, off_t offset, int whence)

第一个参数是文件描述符fd

第二个参数是偏移量,大于0向文件尾偏移,小于0向文件头偏移

第三个参数是从哪里开始偏移,有三个值:SEEK_SET(从文件开头)、SEEK_CUR(从当前位置)、SEEK_END(从文件末尾)

如果成功返回从文件开头的偏移位置(以字节为单位)。 出错返回-1 并设置errno

Linux 使用系统调用进行文件读写相关推荐

  1. Linux高级编程--05.文件读写

    缓冲I/O和非缓冲I/O 文件读写主要牵涉到了如下五个操作:打开.关闭.读.写.定位.在Linux系统中,提供了两套API, 一套是C标准API:fopen.fclose.fread.fwrite.f ...

  2. 写文件函数 Linux C fwrite,C文件读写函数介绍(转)

    1.fopen() fopen的原型是:FILE *fopen(const char *filename,const char *mode),fopen实现三个功能:为使用而打开一个流,把一个文件和此 ...

  3. Linux下c语言文件读写函数总结

    1.FILE *fopen(const char *filename, const char *mode) "r" 打开一个用于读取的文件.该文件必须存在. "w&quo ...

  4. 文件编程之Linux下系统调用

    说明: linux下文件编程可使用两种方法: ****linux系统调用 ****C语言库函数 前者依赖于linux系统,后者与操作系统是独立的. 在任何操作系统下,使用C语言库函数操作文件的方法都是 ...

  5. C语言文件读写操作,写入数据到文件

    很早写的在linux系统下的文件读写操作,写入数据到文件,很时候初学者学习 #include <stdio.h>int writeInfoToFile(char *strFile) {in ...

  6. 外网访问arm嵌入式linux_嵌入式Linux系统编程——文件读写访问、属性、描述符、API

    Linux 的文件模型是从 Unix 的继承而来,所以 Linux 继承了 UNIX 本身的大部分特性,然后加以扩展,本章从 UNIX 系统接口来描述 Linux 系统结构的特性. 操作系统是通过一系 ...

  7. Linux文件读写机制及优化方式

    本文只讨论Linux下文件的读写机制,不涉及不同读取方式如read,fread,cin等的对比,这些读取方式本质上都是调用系统api read,只是做了不同封装.以下所有测试均使用open, read ...

  8. linux存储--从内核文件系统看文件读写过程(四)

    系统调用 操作系统的主要功能是为管理硬件资源和为应用程序开发人员提供良好的环境,但是计算机系统的各种硬件资源是有限的,因此为了保证每一个进程都能安全的执行.处理器设有两种模式:"用户模式&q ...

  9. Linux C高级编程——文件操作之系统调用

    Linux C高级编程文件操作之系统调用 宗旨:技术的学习是有限的,分享的精神是无限的! 库函数是一些完成特定功能的函数,一般由某个标准组织制作发布,并形成一定的标准.使用库函数编写的函数一般可以应用 ...

  10. linux gcc编译下的文件读写操作

    linux下的文件操作 所有目录             1.文件及文件系统的定义             2.linux文件的类型             3.linux文件的权限          ...

最新文章

  1. 前端开发之retina屏幕
  2. 李飞飞:人工智能应用广泛 但场景理解不如2岁孩子
  3. struts工作流程
  4. 服务器性能指标有哪些
  5. ZED 相机 ORB-SLAM2安装环境配置与ROS下的调试
  6. Android_Fragment_Fragment详解
  7. 能测试快充真假的软件,苹果iOS 12可自行测试真假快充:山寨充电器将被洗牌
  8. 向下一代互联网迈进 声网发布全链路加速FPA为互联网增加QoS保障
  9. jmeter 高并发测试报告_JMeter分布式测试
  10. iOS:Xcode7下创建 .a静态库 和 .framework静态库
  11. CV还要更热闹!旷视刚宣布4.6亿美元融资,商汤:新一轮年内完成
  12. 在shell中获取当前机器的ip地址
  13. sm羞耻任务_羞耻驱动的发展
  14. 大家玩突袭2吗?呵呵我有秘籍哟!
  15. 从奥运门票系统瘫痪到家乐福踩踏事件看软件设计中业务模型的处理
  16. 第五季完美童模 代言人陈梓桐 现场走秀回顾
  17. 使用微软云人工智能,合成带感情的语音
  18. 第三代计算机的集成电路,第三代电子计算机主要元件为集成电路。
  19. ilock计算机联锁系统应用,VPIILOCK型计算机联锁系统MMI操作手册V1.0.0
  20. 浏览器提示“您与此网站之间建立的连接不安全”如何解决

热门文章

  1. java网页制作会说话的汤姆猫_android 仿 会说话的汤姆猫 源码
  2. 基于车辆运动学模型的LQR横向控制算法
  3. 近来学习的一些东西和思考
  4. C语言10.10,查找英文的星期几
  5. Java http响应报文_java中HTTP响应报文是什么意思?详细图解
  6. 反正切熵(Arctangent entropy):2022.7月最新SCI论文
  7. OneNote for Windows10 闪退 的解决办法
  8. 头条号项目玩法:中视频全方位教学
  9. pyqt5标签中的字设置不同字体_PyQt5 控件字体样式等设置的实现
  10. 【每日一P】简单实用的调色原理