1、文件描述符

(1)文件描述符的本质是一个数字,这个数字本质上是进程表中文件描述符表的一个表项,进程通过文件描述符作为index去索引查表得到文件表指针,再间接访问得到这个文件对应的文件表。
(2)文件描述符这个数字是open系统调用内部由操作系统自动分配的,操作系统分配这个fd时也不是随意分配,也是遵照一定的规律的,我们现在就要研究这个规律。
(3)操作系统规定,fd从0开始依次增加。fd也是有最大限制的,在linux的早期版本中(0.11)fd最大是20,所以当时一个进程最多允许打开20个文件。linux中文件描述符表是个数组(不是链表),所以这个文件描述符表其实就是一个数组,fd是index,文件表指针是value
(4)当我们去open时,内核会从文件描述符表中挑选一个最小的未被使用的数字给我们返回。也就是说如果之前fd已经占满了0-9,那么我们下次open得到的一定是10.(但是如果上一个fd得到的是9,下一个不一定是10,这是因为可能前面更小的一个fd已经被close释放掉了)
(5)fd中0、1、2已经默认被系统占用了,因此用户进程得到的最小的fd就是3了。
(6)linux内核占用了0、1、2这三个fd是有用的,当我们运行一个程序得到一个进程时,内部就默认已经打开了3个文件,这三个文件对应的fd就是0、1、2。这三个文件分别叫stdin、stdout、stderr。也就是标准输入标准输出、标准错误
(7)标准输入一般对应的是键盘(可以理解为:0这个fd对应的是键盘的设备文件),标准输出一般是LCD显示器(可以理解为:1对应LCD的设备文件)
(8)printf函数其实就是默认输出到标准输出stdout上了。stdio中还有一个函数叫fpirntf,这个函数就可以指定输出到哪个文件描述符中。

2、常用API

open、close、write、read、lseek

2.1OPEN

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

const char *pathname为需要打开的文件、

flags通过一些宏设置读写权限

O_RDONLY、 O_WRONLY 、O_RDWR(只读 只写 读写)

O_APPEND O_APPEND属性去打开文件时,如果这个文件中本来是有内容的,则新写入的内容会接续到原来内容的后面

O_TRUNC  O_TRUNC属性去打开文件时,如果这个文件中本来是有内容的,则原来的内容会被丢弃。

O_CREAT   O_CREAT若不存在则创建。open函数在使用O_CREAT标志去创建文件时,可以使用第三个参数mode来指定要创建的文件的权限。mode使用4个数字来指定权限的,其中后面三个很重要,对应我们要创建的这个文件的权限标志。譬如一般创建一个可读可写不可执行的文件就用0666

O_EXCL  加上O_EXCL如果文件已经被打开则打开失败

O_NONBLOCK 默认为阻塞模式。添加这个设置为非阻塞模式

O_SYNC write阻塞等待底层完成写入才返回到应用层。

2.2 read

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

2.3 write

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

2.3lseek

    执行read与write函数都会使文件指针移动。lseek函数可以调整文件指针。

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

  参数解释。第一个代表文件描述符、第二个代表移动个数、第三个设置移动头。

   lseek(fd, 0 ,SEEK_SET);//文件指针指向头

   SEEK_SET代表指向头

    SEEK_END代表尾部

   SEEK_CUR代表当前位置

3.3close

  可以通过close关闭打开的文件描述符。

3.4dup和dup2函数

(1)dup系统调用对fd进行复制,会返回一个新的文件描述符(譬如原来的fd是3,返回的就是4)
(2)dup系统调用有一个特点,就是自己不能指定复制后得到的fd的数字是多少,而是由操作系统内部自动分配的,分配的原则遵守fd分配的原则

(3)dup2和dup的作用是一样的,都是复制一个新的文件描述符。但是dup2允许用户指定新的文件描述符的数字。

3.5fcntl的原型和作用

  fcntl函数是一个多功能文件管理的工具箱,接收2个参数+1个变参。第一个参数是fd表示要操作哪个文件,第二个参数是cmd表示要进行哪个命令操作。变参是用来传递参数的,要配合cmd来使用。

4、标准IO库介绍

4.1、标准IO和文件IO有什么区别
(1)看起来使用时都是函数,但是:标准IO是C库函数,而文件IO是linux系统的API
(2)C语言库函数是由API封装而来的。库函数内部也是通过调用API来完成操作的,但是库函数因为多了一层封装,所以比API要更加好用一些。
(3)库函数比API还有一个优势就是:API在不同的操作系统之间是不能通用的,但是C库函数在不同操作系统中几乎是一样的。所以C库函数具有可移植性而API不具有可移植性。
(4)性能上和易用性上看,C库函数一般要好一些。譬如IO,文件IO是不带缓存的,而标准IO是带缓存的,因此标准IO比文件IO性能要更高。

4.2、常用标准IO函数介绍
(1)常见的标准IO库函数有:fopen、fclose、fwrite、fread、ffulsh、fseek

#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 fd=-; //fd 文件描述符
char buf[]={};//字符缓冲区
char writebuf[]="ilovezw";//字符缓冲区
int ret;
//第一步打开
//fd = open ("a.txt",O_RDWR|O_APPEND);
fd = open ("a.txt",O_RDWR);
if(- == fd)
{
perror("文件打开错误");
_exit(-);
}
else
{
printf("文件打开成功,fd=%d.\n",fd);
}
//lseek(fd, 3 ,SEEK_SET);//光标位移3 //第二步读写 ret=write(fd,writebuf,strlen(writebuf));//写函数
if(-==ret)
{
//printf("write error");
perror("write error");
_exit(-);
}
else
{
printf("ret=%d\n",ret);
//lseek(fd, -ret ,SEEK_SET);//光标位移3
}
lseek(fd, ,SEEK_SET);//文件指针指向头
ret=read(fd,buf,);//读文件
if(-==ret)
{
//printf("read error");
perror("read error");
_exit(-);
}
else
{
printf("ret=%d,a.txt=%s\n",ret,buf);
}
//第三步关闭
close(fd);
return ;
}
/*标准IO
*/ #include<stdio.h>
#include<stdlib.h>
#include<string.h> int main(int argc,char * argv[])
{
FILE *fp =NULL;
char buf[];
fp = fopen("1.txt","r+");
if(NULL == fp)
{
perror("fopen");
exit(-);
}
memset(buf,,sizeof(buf));
fwrite("",,,fp);
fseek( fp, , SEEK_SET );
fread(buf,,,fp);
printf("%s\n",buf);
fclose(fp);
return ;
}

linux 文件IO的更多相关文章

  1. 转:Linux 文件IO理解

    源地址http://blog.csdn.net/lonelyrains/article/details/6604851 linux文件IO操作有两套大类的操作方式:不带缓存的文件IO操作,带缓存的文件 ...

  2. 转 漫谈linux文件IO

    在Linux 开发中,有几个关系到性能的东西,技术人员非常关注:进程,CPU,MEM,网络IO,磁盘IO.本篇文件打算详细全面,深入浅出.剖析文件IO的细节.从多个角度探索如何提高IO性能.本文尽量用 ...

  3. 漫谈linux文件IO

    在Linux 开发中,有几个关系到性能的东西,技术人员非常关注:进程,CPU,MEM,网络IO,磁盘IO.本篇文件打算详细全面,深入浅出.剖析文件IO的细节.从多个角度探索如何提高IO性能.本文尽量用 ...

  4. <摘录>linux文件IO

    这篇文章写的比较全面,也浅显易懂,备份下.转载自:http://blog.chinaunix.net/uid-27105712-id-3270102.html 在Linux 开发中,有几个关系到性能的 ...

  5. 2.Linux文件IO编程

    2.1Linux文件IO概述 2.1.0POSIX规范 POSIX:(Portable Operating System Interface)可移植操作系统接口规范. 由IEEE制定,是为了提高UNI ...

  6. linux文件io与标准io

    文件IO实际是API,Linux对文件操作主要流程为:打开(open),操作(write.read.lseek),关闭(close). 1.打开文件函数open(): 涉及的头文件:  #includ ...

  7. Linux文件IO操作

    来源:微信公众号「编程学习基地」 目录 文件操作 Linux文件类型 Linux文件权限 修改文件权限 Linux error 获取系统调用时的错误描述 打印错误信息 系统IO函数 open/clos ...

  8. linux文件IO操作篇 (一) 非缓冲文件

    文件IO操作分为 2 种 非缓冲文件IO 和 缓冲文件IO 它们的接口区别是 非缓冲 open() close() read() write() 缓冲 fopen() fclose() fread() ...

  9. Linux文件IO与通用块层的请求合并

    本文参考https://mp.weixin.qq.com/s/Imt4BW-zoHPpcOpcKZs_AQ, 公众号“Linux阅码场” 请求合并就是将进程内或者进程间产生的在物理地址上连续的多个IO ...

随机推荐

  1. springjdbc使用c3p0连接池报错 java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector

    MyMaincom.test.sunc.MyMaintestMethod(com.test.sunc.MyMain)org.springframework.beans.factory.BeanCrea ...

  2. Python 招聘信息爬取及可视化

    自学python的大四狗发现校招招python的屈指可数,全是C++.Java.PHP,但看了下社招岗位还是有的.于是为了更加确定有多少可能找到工作,就用python写了个爬虫爬取招聘信息,数据处理, ...

  3. python序列成员资格

    可以用做登录操作,判断用户名密码是否正确! 代码示例: database = [ ['], ['], ['], ['] ] username = input("UserName: " ...

  4. FPGA选型

    工欲善其事必先利其器,开发FPGA的第一步,当然是选择一片符合你设计需求的芯片. 但是芯片种类那么多,老板又要你越省越好,硬件工程师也天天问你到底该用哪块芯片,怎么办? 今天正好可以跟大家聊聊这些问题 ...

  5. Scrum立会报告+燃尽图(十一月二十五日总第三十三次):展示博客

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2413 项目地址:https://git.coding.net/zhang ...

  6. gitLab服务器搭建+ rundeck自动化部署

    git服务器搭建 https://blog.csdn.net/gx_1_11_real/article/details/79406427 rundeck   部署 https://blog.csdn. ...

  7. EXT4+Struts2 JSON的问题

    ERROR : Class org.apache.struts2.json.JSONWriter can not access a member of class org.springframewor ...

  8. CDOJ ABCDE dp(前缀和优化)

    题目链接: http://acm.uestc.edu.cn/#/problem/show/1307 ABCDE Time Limit: 1000/1000MS (Java/Others)Memory ...

  9. OC创建对象并访问成员变量

    1.创建一个对象 Car *car =[Car new] 只要用new操作符定义的实体,就会在堆内存中开辟一个新空间 [Car new]在内存中 干了三件事 1)在堆中开辟一段存储空间 2)初始化成员 ...

  10. matlab 图像Mat类型矩阵中的值(uint8)类型转换,防止溢出

    a=[50,60,70; 80,90,50; 100,55,40] 假设a是一个灰度图的mat形式(当然实际的size肯定比这大,我只是举例子),如果需要对这个矩阵的像素进行加减处理,很可能会产生溢出 ...