1.linux系统如何管理文件

硬盘中的静态文件和inode:

(1)硬盘分为两大区域:一个是硬盘内容管理表项,另一个是真正存储内容的区域。先去读取硬盘内容管理表,找到要访问的存储内容的区域,再用得到我们要的文件。

(2)每一个文件有一个信息列表(叫inode,i节点,其实质是一个结构体,有很多元素,每个元素记录了这个文件的信息,有包括文件名、扇区号、块号等信息)

内存中被打开的文件和vnode:

(1)在程序中打开的文件属于某个进程,进程有对应的进程信息表,表中的指针会指向文件管理表,文件管理表中记录了当前进程的相关信息
(2)文件的管理结构体vnode记录了一个被打开的文件的各种信息。


1.多次打开同一文件

(1)设置fd1,fd2读取文件,经过实验验证,证明了结果是fd1和fd2分别读

(2)设置fd1,fd2写入文件,经过实验验证,证明了结果是fd1和fd2分别写

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main(int argc, char *argv[])
{int fd1 = -1, fd2 = -1;      // fd 就是file descriptor,文件描述符char buf[100] = {0};       //用来存放读取文件内容的bufchar writebuf[20] = "l love linux";   int ret = -1;// 第一步:打开同一个文件,返回两个文件描述符fd1 = open("a.txt", O_RDWR | O_TRUNC | O_CREAT , 0666);fd2 = open("a.txt", O_RDWR | O_TRUNC | O_CREAT , 0666);if ((-1 == fd1) || (fd2 == -1))        {perror("文件打开错误");_exit(-1);}else{printf("文件打开成功,fd1 = %d. fd2 = %d.\n", fd1, fd2);}#if 0  //先关掉写文件while (1){// 写文件ret = write(fd1, "ab", 2);if (ret < 0){perror("write失败");_exit(-1);}else{printf("write成功,写入了%d个字符\n", ret);}ret = write(fd2, "cd", 2);if (ret < 0){perror("write失败");_exit(-1);}else{printf("write成功,写入了%d个字符\n", ret);}sleep(1);}
#endif#if 1        //先打开读文件while(1){// 读文件fd1memset(buf, 0, sizeof(buf));      //先清空用来存放读取内容的bufret = read(fd1, buf, 2);         if (ret < 0){printf("read失败\n");_exit(-1);}else{ printf("fd1:[%s].\n", buf);}sleep(1);// 读文件fd2memset(buf, 0, sizeof(buf));ret = read(fd2, buf, 2);if (ret < 0){printf("read失败\n");_exit(-1);}else{   printf("fd2:[%s].\n", buf);}}#endif    // 第三步:关闭文件close(fd1);close(fd2);_exit(0);
}

(3)有时候我们希望接续写而不是分别写?办法就是在open时加O_APPEND标志即可,对文件的读写是原子操作。


2.文件共享的实现方式

(1)文件共享就是同一个文件被多个独立的读写体去同时操作。
(2)常见的有3种文件共享的情况:第一种同一个进程中多次使用open打开同一个文件第二种是在不同进程中去分别使用open打开同一个文件(这时候因为两个fd在不同的进程中,所以两个fd的数字可以相同也可以不同),第三种情况是后面要学的,linux系统提供了dup和dup2两个API来让进程复制文件描述符。

(3)dup和dup2函数

使用dup进行文件描述符复制:会返回一个新的文件描述符

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>#define FILENAME   "1.txt"int main(void)
{int fd1 = -1, fd2 = -1;fd1 = open(FILENAME, O_RDWR | O_CREAT | O_TRUNC, 0644);if (fd1 < 0){perror("open");return -1;}printf("fd1 = %d.\n", fd1);close(1);       // 1就是标准输出stdout// 复制文件描述符fd2 = dup(fd1);      // fd2一定等于1,因为前面刚刚关闭了1,这句话就把if (fd2 < 0)        // 1.txt文件和标准输出就绑定起来了,所以以后输出{                   // 到标准输出的信息就可以到1.txt中查看了。perror("dup");return -1;}                   printf("fd2 = %d.\n", fd2);printf("this is for test\n");close(fd1);return -1;
}

dup2复制的文件描述符:dup2允许用户指定新的文件描述符的数字

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>#define FILENAME   "1.txt"int main(void)
{int fd1 = -1, fd2 = -1;fd1 = open(FILENAME, O_RDWR | O_CREAT | O_TRUNC, 0644);if (fd1 < 0){perror("open");return -1;}printf("fd1 = %d.\n", fd1);fd2 = dup2(fd1, 16);printf("fd2 = %d.\n", fd2);while (1){write(fd1, "aa", 2);sleep(1);write(fd2, "bb", 2);}close(fd1);return -1;
}


3.fcntl函数
(1)fcntl的常用cmd,F_DUPFD这个cmd的作用是复制文件描述符(作用类似于dup和dup2)

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>#define FILENAME   "1.txt"int main(void)
{int fd1 = -1, fd2 = -1;fd1 = open(FILENAME, O_RDWR | O_CREAT | O_TRUNC, 0644);if (fd1 < 0){perror("open");return -1;}printf("fd1 = %d.\n", fd1);fd2 = fcntl(fd1, F_DUPFD, 6);printf("fd2 = %d.\n", fd2);while (1){write(fd1, "aa", 2);sleep(1);write(fd2, "bb", 2);}close(fd1);return -1;
}


4.标准IO库

(1)标准IO是C库函数,而文件IO是linux系统的API

(2)常见的标准IO库函数有:fopen、fclose、fwrite、fread、ffulsh、fseek

读文件代码:

#include <stdio.h>     // standard input output
#include <stdlib.h>
#include <string.h>#define FILENAME   "1.txt"int main(void)
{FILE *fp = NULL;size_t len = -1;char buf[100] = {0};        //用来储存读取文件的内容fp = fopen(FILENAME, "r+");if (NULL == fp){perror("fopen");exit(-1);}printf("fopen success. fp = %p.\n", fp);// 在这里去读文件memset(buf, 0, sizeof(buf));len = fread(buf, 1, 10, fp);printf("len = %d.\n", len);printf("buf is: [%s].\n", buf);fclose(fp);return 0;
}

写文件代码:

#include <stdio.h>     // standard input output
#include <stdlib.h>
#include <string.h>#define FILENAME   "1.txt"int main(void)
{FILE *fp = NULL;size_t len = -1;int array[10] = {1, 2, 3, 4, 5};
fp = fopen(FILENAME, "w+");if (NULL == fp){perror("fopen");exit(-1);}printf("fopen success. fp = %p.\n", fp);// 在这里去写文件len = fwrite(array, 4, 10, fp);printf("len = %d.\n", len);fclose(fp);return 0;
}

Linux操作与管理文件(多次打开同一文件,文件共享,fcntl函数,标准IO库)相关推荐

  1. linux下两个进程可以同时打开同一个文件吗?返回的文件描述符一样吗?

    Linux下两个进程可以同时打开同一个文件吗?返回的文件描述符一样吗? 一:结论 1.两个进程中分别产生生成两个独立的fd 2.两个进程可以任意对文件进行读写操作,操作系统并不保证写的原子性 3.进程 ...

  2. 基于嵌入式linux 的蓝牙通信系统设计与实现的研究意义,嵌入式Linux操作系统通信管理机的设计研究...

    摘 要 随着信息技术的发展,各种操作技术.操作系统不断更新,而通信管理机是自动化系统的数据枢纽,在自动化系统中担任重要角色,在本文中我们对嵌入式Linux操作系统的特点.通信管理机制等方面进行研究分析 ...

  3. python输入文件名读取文件_[Python] python3 文件操作:从键盘输入、打开关闭文件、读取写入文件、重命名与删除文件等...

    1.从键盘输入 Python 2有两个内置的函数用于从标准输入读取数据,默认情况下来自键盘.这两个函数分别是:input()和raw_input(). Python 3中,不建议使用raw_input ...

  4. IOC操作Bean管理XML方式(外部属性文件)

    目录 IOC操作Bean管理XML方式(外部属性文件) 前情引入: 实验演示: 1.直接配置数据库信息 (1)配置德鲁伊连接池 (2)引入德鲁伊连接池jar包 (3)创建一个bean6.xml配置文件 ...

  5. php dat文件,window_Win7系统怎么打开Dat文件 Win7系统打开Dat文件的方法,  在电脑中的Dat文件是很常 - phpStudy...

    Win7系统怎么打开Dat文件 Win7系统打开Dat文件的方法 在电脑中的Dat文件是很常见的,但是怎样打开这个Dat文件,还是有很多人不是很了解.如果用户在使用Win7系统时,当点击保存的时候,那 ...

  6. c语言打开xls文件格式,Excel2017如何打开et格式文件?Excel2017打开.et文件的方法介绍...

    使用Excel2017如何打开后缀名为.et的文件?如果电脑里有.et文件,那么系统默认的打开软件是WPS表格,但是很多人的电脑里安装的多是Excel办公软件,那么有没有什么办法将其转换成Excel可 ...

  7. MyEclipse打不开项目下的jsp文件,或是打开jsp文件报错!

    MyEclipse打不开项目下的jsp文件,或是打开jsp文件报错! 解决:出现此问题的根本原因是因为MyEclipse编译器默认的打开jsp文件的方式不对! 下面是设置MyEclipse打开jsp的 ...

  8. 【我的OpenGL学习进阶之旅】什么是TGA文件以及如何打开TGA文件?

    目录 一.问题描述 二.解决问题:打开TGA文件 三.什么是TGA文件? 四. 如何打开TGA文件 4.1. 使用图像编辑器打开TGA文件 4.2. 使用Pain.Net打开TGA文件 4.3.使用T ...

  9. NOTES邮箱打不开,提示打开的文件出错(打开的文件时出错)。

    . NOTES 邮箱打不开,提示打开的文件出错(打开的文件时出错). <?xml:namespace prefix = o ns = "urn:schemas-microsoft-co ...

最新文章

  1. 使用 Eigen 库写第一个程序
  2. MySQL 高可用架构 之 MHA (Centos 7.5 MySQL 5.7.18 MHA 0.58)
  3. python学习高级篇(part3)--MRO
  4. HTML 标记大全参考手册
  5. vue mxgraph渲染xml页面_Vue的两个版本
  6. 实战深度强化学习DQN-理论和实践
  7. c语言中八进制转换成十进制数,C语言中的二进制、八进制、十进制之间的转换...
  8. matlab 判断元素索引_MATLAB图像处理:08:在交通视频中检测汽车
  9. 关于返回二维数组排序后序号数组的问题求解
  10. 部署git服务器(Windows Server 2008)
  11. 【算法与数据结构】哈希表-链地址法
  12. Java大数类自我需要掌握的
  13. TPS、RPS和QPS是什么
  14. android补间动画有哪几种,android三种动画详解(补间动画、帧动画、属性动画)...
  15. 寻找那些神奇的自幂数---C语言
  16. 电脑如何查看如何无限WiFi密码?
  17. java uuid去掉横线_UUID去横杠-的正确方式
  18. 微信h5分享图标没有展示
  19. 操作Linux软链接引起的各种问题
  20. [架构之路-159]-《软考-系统分析师》-10-系统分析-6-现有业务流程分析, 系统分析最核心的任务

热门文章

  1. ios移动端滑动抖动的bug
  2. 第十届蓝桥杯国赛C/C++ 大学B组 试题C: 拼接
  3. 中科爱讯WiFi探针在客流分析统计的应用
  4. 计算机服务怎么打开flash,开启Flash Helper Service服务后自动关闭要怎么解决?
  5. ISCC2021——wp
  6. 内网xshell传输文件命令_Xshell 传输文件
  7. 3dsmax小车模型
  8. jquery input值发生变化时,时时触发事件 input propertychange 、 cheng
  9. 有限元方法简介与COMSOL操作入门
  10. word 2007 中的 aurora 插件配置