Linux什么是文件IO,linux中文件IO
一. linux常用文件IO接口
1.1. 文件描述符
1.1.1. 文件描述符的本质是一个数字,这个数字本质上是进程表中文件描述符表的一个表项,进程通过文件描述符作为index去索引查表得到文件表指针,再间接访问得到这个文件对应的文件表。
1.1.2. 文件描述符这个数字是open系统调用内部由操作系统自动分配的,操作系统分配这个fd时也不是随意分配,也是遵照一定的规律的:fd从0开始依次增加。fd也是有最大限制的,在linux的早期版本中(0.11)fd最大是20,所以当时一个进程最多允许打开20个文件。linux中文件描述符表是个数组(不是链表),所以这个文件描述符表其实就是一个数组,fd是index,文件表指针是value。当我们去open时,内核会从文件描述符表中挑选一个最小的未被使用的数字给我们返回。
1.1.3. fd中0、1、2已经默认被系统占用了,因此用户进程得到的最小的fd就是3了。这三个文件对应的fd就是0、1、2。这三个文件分别叫stdin、stdout、stderr。也就是标准输入、标准输出、标准错误。
1.2. open
1.2.1. 在linux系统中要操作一个文件,一般是先open打开一个文件,得到一个文件描述符,然后对文件进行读写操作(或其他操作),最后close关闭文件即可
1.2.2. 文件平时是存在块设备中的文件系统中的,我们把这种文件叫静态文件。当我们去open打开一个文件时,linux内核做的操作包括:内核在进程中建立了一个打开文件的数据结构,记录下我们打开的这个文件;内核在内存中申请一段内存,并且将静态文件的内容从块设备中读取到内存中特定地址管理存放(叫动态文件)。
1.2.3. 打开文件后,以后对这个文件的读写操作,都是针对内存中这一份动态文件的,而并不是针对静态文件的。当我们对动态文件进行读写后,此时内存中的动态文件和块设备中的静态文件就不同步了,当我们close关闭动态文件时,close内部内核将内存中的动态文件的内容去更新(同步)块设备中的静态文件。这样做主要由于:块设备本身有读写限制(回忆NnadFlash、SD等块设备的读写特征),本身对块设备进行操作非常不灵活。而内存可以按字节为单位来操作,而且可以随机操作(内存就叫RAM,random),很灵活。所以内核设计文件操作时就这么设计了。
1.3. read
ssize_t read(int fd,void *buf,size_t count);
@H_404_4@
View Code
@H_404_4@
a. fd表示要读取哪个文件,fd一般由前面的open返回得到
b. buf是应用程序自己提供的一段内存缓冲区,用来存储读出的内容
c. count是我们要读取的字节数
d. 返回值ssize_t类型是linux内核用typedef重定义的一个类型(其实就是int),返回值表示成功读取的字节数。
1.4. write
ssize_t write(int fd,const void *buf,size_t count);
@H_404_4@
View Code
@H_404_4@
1.4.1. 写入用write系统调用,write的原型和理解方法和read相似
1.5. lseek
off_t lseek(int fd,off_t offset,int whence);
@H_404_4@
View Code
@H_404_4@
1.5.1. 文件指针:当我们要对一个文件进行读写时,一定需要先打开这个文件,所以我们读写的所有文件都是动态文件。动态文件在内存中的形态就是文件流的形式。
1.5.2. 在动态文件中,我们会通过文件指针来表征这个正在操作的位置。所谓文件指针,就是我们文件管理表这个结构体里面的一个指针。所以文件指针其实是vnode中的一个元素。这个指针表示当前我们正在操作文件流的哪个位置。这个指针不能被直接访问,linux系统用lseek函数来访问这个文件指针。
1.5.3. 当我们打开一个空文件时,默认情况下文件指针指向文件流的开始。所以这时候去write时写入就是从文件开头开始的。write和read函数本身自带移动文件指针的功能,所以当我write了n个字节后,文件指针会自动向后移动n位。如果需要人为的随意更改文件指针,那就只能通过lseek函数了
1.5.4. 用lseek计算文件长度(length = lseek(fd,SEEK_END))
1.6. close
int close(int fd);
@H_404_4@
View Code
@H_404_4@
1.6.1. 关闭打开的文件
PS:实时查man手册
(1)当我们写应用程序时,很多API原型都不可能记得,所以要实时查询,用man手册
(2)man 1 xx查linux shell命令,man 2 xxx查API, man 3 xxx查库函数
二. open函数的flag详解
2.1. 读写权限
a. O_RDONLY就表示以只读方式打开,
b. O_WRONLY表示以只写方式打开,
c. O_RDWR表示以可读可写方式打开
2.2. 打开存在并有内容的文件时
2.3. 打开不存在的文件时
2.4. O_NONBLOCK
2.5. O_SYNC
三. 文件读写的一些细节
3.1. errno
3.2. perror
3.3. 文件IO效率和标准IO
四. 退出进程方式
4.1. 在main(main函数由其父进程调用,故返回后进程就over)用return,一般原则是程序正常终止return 0,如果程序异常终止则return -1。
4.2. 正式终止进程(程序)应该使用exit或者_exit或者_Exit之一。
五. 文件共享的实现方式
#include #include#include#include#include#include
int main(int argc,char *argv[])
{int fd1 = -1,fd2 = -1; //fd 就是file descriptor,文件描述符
char buf[100] = {0};char writebuf[20] = "l love linux";int ret = -1;//第一步:打开文件
fd1 = open("a.txt",O_RDWR);
fd2= open("a.txt",O_RDWR);//fd = open("a.txt",O_RDONLY);
if ((-1 == fd1) || (fd2 == -1)) //有时候也写成: (fd < 0)
{//printf("\n");
perror("");//return -1;
_exit(-1);
}else{
printf("文件打开成功,fd1 = %d. fd2 = %d.\n",fd1,fd2);
}#if 0
//第二步:读写文件//write(fd,writebuf,strlen(writebuf));if (ret < 0)
{//printf("write失败.\n");
perror("write失败");
_exit(-1);
}else{
printf("write成功,写入了%d个字符\n",ret);
}#endif
#if 1
while(1)
{//0,sizeof(buf));
ret= read(fd1,buf,2);if (ret < 0)
{
printf("read失败\n");
_exit(-1);
}else{//printf("实际读取了%d字节.\n",ret);
printf("fd1:[%s].\n",buf);
}
sleep(1);//sizeof(buf));
ret= read(fd2,ret);
printf("fd2:[%s].\n",buf);
}
}#endif
//第三步:关闭文件
close(fd1);
close(fd2);
_exit(0);
}
@H_404_4@
View Code
@H_404_4@
@H_404_4@
相关文章
猜你在找的Linux相关文章
禁止软件升级 sudo echo 软件包名 hold | sudo dpkg --set-selections 取消软件禁止升级的限制 sudo echo 软件包名 install | sudo dp
译 原文作者:Bobbin Zachariah 原文链接:https://linoxide.com/linux-command/essential-linux-basic-commands/ @ 在本
规则包含两个部分,一个是依赖关系,一个是生成目标的方法。在Makefile中,规则的顺序是很重要的,因为,Makefile中只应该有一个最终目标,其它的目标都是被这个目标所连带出来的,所以一定要让make知道你的最终目标是什么。一般来说,定义在Makefile中的目标可能会有很多,但是第一条规则中的目标将被确立为最终的目标。如果第一条规则中的目标有很多个,那么,第一个
#!/bin/bashname=Tomif grep "$name" databasefile > /dev/null 2>&1then :else echo "$1 not found in databasefile" exit 1fi#!/bin/bash# Scriptname: nosyecho -e "Ar
1、name=${name2:-word}当name2这个变量已经设置过了(就是说name2这个变量设置过值),则把它的值赋值给name。如果name2这个变量没有设置过值,则把word当作name的值。2、name=${name2:=word}当name2这个变量已经设置过了,就把name2的值赋值给name这个变量,如果name2没有设置过,则把word赋值给name23
/etc/init.d 这个目录是用来存放系统或服务器以System V模式启动的脚本,这在以System V模式启动或初始化的系统中常见。比如Fedora/RedHat;/etc/xinit.d 如果服务器是通过xinetd模式运行的,它的脚本要放在这个目录下。有些系统没有这个目录, 比如Slackware,有些老的版本也没有。在Rehat/Fedora中比较新的版
在POSIX shell中,命令的结果可以通过%>;的形式来定义(其中%表示文件描述符:1为标准输出stdout、2为标准错误 stderr)! 系统默认%值是1,也就是1>;,而1>;可以简写为>;,也就是默认为>;。而stdout的默认目标是终端(这点不用验证吧)。另外,stderr的默认目标我个人认为也是终端,比如:#abcddcbash: abcddcba: not
Linux什么是文件IO,linux中文件IO相关推荐
- 移动硬盘linux无权限,ubuntu上移动硬盘中文件没有可执行权限的解决方法
ubuntu上移动硬盘中文件没有可执行权限的解决方法,移动硬盘自动挂载到ubuntu上后,移动硬盘中的文件没有可执行权限的解决方法如下: 例如我的移动硬盘卷标为:workspace 当把移动硬盘插入P ...
- IO流中文件和文件夹的删除程序举例
/* * 删除功能(无论是文件夹还是文件都是用delete方法,仅仅能一级一级的删除.):public boolean delete() * * 注意: * A:假设你创建文件或者目录忘了写盘符路径, ...
- mysql数据库管理文件_数据库管理中文件的使用教程
摘要:这篇MySQL栏目下的"数据库管理中文件的使用教程",介绍的技术点是"数据库管理.使用教程.数据库.的使用.文件.管理",希望对大家开发技术学习和问题解决 ...
- mysql数据库管理文件_数据库管理中文件的使用_MySQL
bitsCN.com 数据库管理中文件的使用 从文本文件中读取数据(import) 常用的文本文件:CSV(Comma Separated Values)文件,即:以逗号分隔的数值 形式如下: [pl ...
- python文件式_python中文件操作的六种模式及对文件某一行进行修改的方法
一.python中文件操作的六种模式分为:r,w,a,r+,w+,a+ r叫做只读模式,只可以读取,不可以写入 w叫做写入模式,只可以写入,不可以读取 a叫做追加写入模式,只可以在末尾追加内容,不可以 ...
- java文件选择器_java中文件选择器JFileChooser的用法
一般的说,大家用JFileChooser有两种用法:打开文件或文件夹.保存文件或文件夹.本文就打开和保存文件来介绍JFileChooser的用法. 头文件的声明: import javax.swing ...
- c语言中 文件,c语言中文件的使用方法
c语言中文件的使用方法 一.文件指针的定义 FILE *fp//注意FILE的大写 二.文件的打开 fp=fopen("(路径)文件名.文件格式后缀","文件的使用方法& ...
- python对文件操作-python中文件操作的其他方法
Python中文件操作的一般方法,包括打开,写入,关闭.本文中介绍下python中关于文件操作的其他比较常用的一些方法. 首先创建一个文件poems: p=open("poems" ...
- windows分区给linux根目录,装了双系统,为何在linux中看不到我windows中文件分区里的东东啊??!...
你的wubi安装在过程中应该失败了.安装程序进入了硬盘安装的过程,此时要格盘建分区(通常是两个:swap和"/"根目录挂载点).Wubi安装很简单的. 你的问题我不是很明白,wub ...
- img src 文件流_Java中的IO流之输出流|乐字节
大家好,乐字节小乐又来咯,上次讲到了IO流的输入流,本文将讲述Java输出流. Java输入输出流 一.输出流 1.抽象类:OutputStream 和 Writer OutputStream和Wri ...
最新文章
- codevs1258 关路灯(☆区间dp)
- 从谷歌离职回到西湖大学,只为让AI听懂你的悲伤!
- iptables命令_理解 Linux 下的 Netfilter/iptables
- linux 7 zip软件下载,linux安装使用7zip教程
- Python入门教程以及资料免费下载
- iOS开发之tintColor属性详解
- 服务器本地打开asp文件路径,服务器本地打开asp文件
- ecshop验证码无法显示
- powermockito测试私有方法_Spock代码讲解 静态方法测试
- Java编程输出你的年龄和姓名
- python 保存scv文件乱码与报错的问题解决TypeError: a bytes-like object is required, not 'str'
- 无线通信设备安装工程概预算编制_深圳电气工程造价培训-电气设备安装工程造价入门级知识学习...
- java word书签_JAVA 创建移除Word书签
- RabbitMQ报错 o.s.a.r.c.CachingConnectionFactory : Channel shutdown: channel error; protocol meth
- 关于make提示must been abled with the -std=c++11 or -std=gnu++11 compiler options
- 使用css3d-engine.js编写简单的 360全景h5页面
- 2021-12-29 网工基础(十六)动态路由OSPF基础
- CMMI-3级kpa
- 2020清华大学计算机学院黄翔,清华大学计算机科学与技术系2020—2021学年度学生会主席候选人名单公示...
- ATJ2157内存篇【炬芯音频芯片】---sct语法
热门文章
- 2009.5.23软考_信息处理技术员 上午试题 答案 讨论
- Yahoo! UI Library入门
- fatal error C1900: Il mismatch between 'P1' version '20060201' and 'P2' version '20050411'
- 常见的复杂网络模型都有哪些?
- CVX约束中定义中间变量或表达式
- WIN10 OpenGL GLFW+GLAD 开发环境搭建
- SSD+HDD双硬盘+MSI主板win8.1+ubuntu17.04双系统安装总结
- android Button 监听的几种方式
- linux-tq2440
- Nginx配置服务器静态文件支持跨域访问