文件IO与标准IO及非阻塞IO(非阻塞转)

标准IO与文件IO linux下文件操作包含下面4个头文件: 阅读详情

应用程序
——————————
内核 驱动 操作系统 系统移植

--------------------
硬件
API库
应用程序------>内核

系统编程 I/O 进程 网络

直接API 间接(减少了系统调用效率更高)
I/O分为 文件I/O----->内核标准I/O--------->内核

ps -axj 查看系统进程信息

#include "stdio.h"
#include "unistd.h"
#include "stdlib.h" //close() read() write() lseek()
#include "sys/types.h"//常用的宏
#include "fcntl.h" //open()
#include"string.h"
int main()
{
int fd;
int ret;
char str[]="ssddff";
char readstr[100];
memset(readstr,0,sizeof(readstr)); //数组清零
fd=open("/home/0414/abc",O_RDWR|O_TRUNC,0777);//返回文件描述符
if(fd==-1)
{
printf("open file failure\n");
exit(-1);
}
printf("open file sucess\n");
ret=write(fd,str,sizeof(str)); //返回真实写入的字符长度
lseek(fd,0,SEEK_SET); //修改当前文件位移量
printf("write %d byte in file abc\n",ret);
ret=read(fd,readstr,5); //返回读取到的字符长度
printf("read %d byte in file abc is %s\n",ret,readstr);
close(fd);
return 0;
}

原型 int open(const char *pathname, int flags, mode_t mode);
参数 pathname 被打开的文件名(可包括路径名)。


O_RDONLY:只读方式打开文件。

O_WRONLY:可写方式打开文件。(这三个参数互斥)
O_RDWR:读写方式打开文件。

O_CREAT:如果该文件不存在,就创建一个新的文件,并用第三的参数为其设置权限。
O_EXCL:如果使用O_CREAT时文件存在,则可返回错误消息。这一参数可测试文件是否存在。
O_NOCTTY:使用本参数时,如文件为终端,那么终端不可以作为调用open()系统调用的那个进程的控制终端。
O_TRUNC:如文件已经存在,那么打开文件时先删除文件中原有数据。
O_APPEND:以添加方式打开文件,所以对文件的写操作都在文件的末尾进行。
mode 被打开文件的存取权限,为8进制表示法。

原型 off_t lseek(int fd,off_t offset,int whence);
参数 fd:文件描述符。
offset:偏移量,每一读写操作所需要移动的距离,单位是字节的数量,可正可负(向前移,向后移)
whence
(当前位置基点): SEEK_SET:当前位置为文件的开头,新位置为偏移量的大小。
SEEK_CUR:当前位置为文件指针的位置,新位置为当前位置加上偏移量。
SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量的大小
返回值 成功:文件的当前位移

-1:出错


通过一个简单的copy程序,完成文件的复制程序,了解基本的文件I/O文件读写的基本步骤

编写代码,实现相应的功能

打开源文件

打开目标文件

循环读取源文件并写入目标文件

关闭源文件

关闭目标文件

#include<stdio.h>
#include"unistd.h"
#include"stdlib.h"
#include"sys/types.h"
#include"fcntl.h"
#define max 256
int main(int argc,char *argv[])
{
int fd1;
int fd2;
int i;
char str[max];
if(argc != 3)
{
printf("the command error!");
exit(-1);
}
fd1 = open(argv[1],O_RDONLY);
if(fd1 == -1)
{
printf("open file failure\n");
exit(-1);
}
fd2 = open(argv[2],O_WRONLY|O_CREAT|O_APPEND|O_TRUNC,0777);
if(fd2==-1)
{
printf("open file failure\n");
exit(-1);
}
if(fd2 == -1)
{
printf("open file failure\n");
exit(-1);
}
do
{
i=read(fd1,str,max);
write(fd2,str,i);

}while(i==256);
return 0;

}

 

 

标准I/O有三种缓存1全缓存 2行缓存 3无缓存


inode---结构体---------指针---------
ext3 / \ |
| 磁盘块(文件内容,软链接指针) <
|
|
| inode-------------------
目录 | |
磁盘块(文件名链表形式)<----


软链接 ln -s xx cc “快捷方式”
硬链接 ln xx cc “对文件xx的备份”

一个小例子
#include<stdio.h>
int main()
{
printf("hello linux");
(____________________)
}
1 _exit(0); 2 fflush(stdout);_exit(0); 3 exit(0);

umask 取反后与设定的权限相与

打开函数文件描述符open(文件位置,打开方式,权限)
文件流指针fopen(文件位置,打开方式)
r只读文件存在 +读写 w写,没有文件创建,清零 a写没有文件创建,追加

fgetc(fp) fgets(buf,100,fp) fread(指针,size,num,fp)
fputc(int c,fp) fputs(buf,fp) fwrite(同上)
用以上3对函数编写复制函数

#include<stdio.h>
#include"stdlib.h"
int main(int argc,char *argv[])
{
FILE *fd1;
FILE *fd2;
char i;
if(argc != 3)
{
printf("the command error!");
  exit(-1);
}
fd1 = fopen(argv[1],"r");
if(fd1 == NULL)
{
printf("open file failure\n");
exit(-1);
}
fd2 = fopen(argv[2],"w");
if(fd2==NULL)
{
printf("open file failure\n");
exit(-1);
}
while((i=fgetc(fd1))!=EOF)
{
fputc(i,fd2);
}
return 0;

}

#include<stdio.h>
#include"stdlib.h"
#include"string.h"
#define N 100
int main(int argc,char *argv[])
{
FILE *fd1;
FILE *fd2;
int i=0;
char str[N];
if(argc != 3)
{
printf("the command error!");
exit(-1);
}
fd1 = fopen(argv[1],"r");
if(fd1 == NULL)
{
printf("open file failure\n");
exit(-1);
}
fd2 = fopen(argv[2],"w");
if(fd2==NULL)
{
printf("open file failure\n");
exit(-1);
}
while(fgets(str,N,fd1)!=NULL)
{
if(strlen(str)<N-1)
{
i++;
}
else
if(str[N-2]=='\n')
i++;

fputs(str,fd2);

}
printf("%d\n",i);

return 0;

}

#include<stdio.h>
#include"stdlib.h"
#define N 100
int main(int argc,char *argv[])
{
FILE *fd1;
FILE *fd2;
int i;
char str[N];
if(argc != 3)
{
printf("the command error!");
exit(-1);
}
fd1 = fopen(argv[1],"r");
if(fd1 == NULL)
{
printf("open file failure\n");
exit(-1);
}
fd2 = fopen(argv[2],"w");
if(fd2==NULL)
{
printf("open file failure\n");
exit(-1);
}
do
{
i=fread(&str,1,N,fd1);
fwrite(&str,1,i,fd2);
}while(i==N);

return 0;

}

原帖地址http://blog.youkuaiyun.com/ubuntulover/article/details/4443458

1.以非阻塞方式打开文件

调用open时,使用O_NONBLOCK选项即可。

实例:

//noblock.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#define MAX 100000
#define LEN 1024

int main(int argc, char *argv[ ])
{
int fd1, fd2;
FILE *fp;
char buf[MAX];
int n, rest;
char *p = buf;
char content[LEN];

if(argc != 3){
printf("expect args/n");
exit(1);
}

fd1 = open(argv[1], O_RDONLY);
if(fd1 == -1){
perror("fail to read");
exit(1);
}

fp = fopen(argv[2], "w");
if(fp == NULL){
perror("fail to read");
exit(1);
}

fd2 = open("test.txt", O_WRONLY);
if(fd2 == -1){
perror("fail to read");
exit(1);
}

rest = read(fd1, buf, MAX);
printf("get %d bytes from %s/n", rest, argv[1]);

while(rest > 0){
errno = 0;
n = write(fd2, p, rest);

fprintf(fp, "write %d, errno %s/n", n, strerror(errno));
if(rest > 0){
p += n;
rest -= n;
}
}

printf("done/n");

return 0;
}

观察输出系统中调用出错原因的文件,可以看到很多错误号为EAGAIN的出错提示信息。

2.将一个打开的文件设置为非阻塞方式

用fcntl,先用F_GETFL得到状态标志字,之后用F_SETFL设置相应的位。

//noblock_fcntl.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#define MAX 100000
#define LEN 1024

int main(int argc, char *argv[ ])
{
int fd1, fd2;
FILE *fp;
char buf[MAX];
int n, rest;
char *p = buf;
char content[LEN];
int flags;

if(argc != 3){
printf("expect args/n");
exit(1);
}

fd1 = open(argv[1], O_RDONLY);
if(fd1 == -1){
perror("fail to read");
exit(1);
}

fd2 = open(argv[2], O_WRONLY);
if(fd2 == -1){
perror("fail to read");
exit(1);
}

fp = fdopen(fd2, "w");
if(fp == NULL){
perror("fail to open");
exit(1);
}

flags = fcntl(STDOUT_FILENO, F_GETFL, 0);
if(flags == -1){
perror("fail to fcntl");
exit(1);
}
flags |= O_NONBLOCK;
if(fcntl(STDOUT_FILENO, F_SETFL, flags) == -1){
perror("fail to fcntl");
exit(1);
}

rest = read(fd1, buf, MAX);
printf("get %d bytes from %s/n", rest, argv[1]);

while(rest > 0){
errno = 0;
n = write(STDOUT_FILENO, p, rest);

fprintf(fp, "write %d, errno %s/n", n, strerror(errno));
if(rest > 0){
p += n;
rest -= n;
}
}

printf("done/n");

close(fd1);

fclose(fp);

return 0;
}

 

同步IO、异步IO、阻塞IO、非阻塞IO之间的联系与区分 POSIX 首先了解下什么是posix 可移植操作系统接口(英语:Portable Operating System Interface,缩写为POSIX)是IEEE为要在各种UNIX操作系统上运行软件,而定义API的一系列互相关联的标准的总称,其正式称呼为IEEE Std 1003,而国际标准名称为ISO/IEC 9945。此标准源于一个大约开始于1985年的项目。POSIX这个名称是由理查德·斯托曼(RMS)应IEEE的要求而提议的一个易于记忆的名称。它基本上是Portable Operating Sy 阅读详情

相关推荐

pgsql行列转换

‌是PostgreSQL中的一个函数,用于将一个字符串根据正则表达式进行分割,并将结果返回为一个表格,每个分割后的部分作为一行‌‌。string_agg() 函数是 PostgreSQL 中的一个聚合函数,用于将一个列中的值连接成一个字符串。

chimchim66的博客 3501

Linux(C/C++)下的文件操作open、fopen与freopen

Linux(C/C++)下的文件操作open、fopen与freopen

a656343072的专栏 4万+

告别卡顿!用LVGL+DMA刷新STM32F407的SPI屏幕,性能提升实战

本文详细介绍了如何通过LVGL+DMA技术优化STM32F407驱动SPI屏幕的性能,实现接近60FPS的流畅刷新。从硬件瓶颈分析到SPI与DMA的精细化配置,再到LVGL的双缓冲机制与局部刷新优化,提供了一套完整的性能提升方案。特别适合嵌入式GUI开发中面临卡顿问题的工程师参考。

weixin_42531588的博客 378

C语言文件操作

一 缓冲文件系统   缓冲文件系统的特点是:在内存开辟一个“缓冲区”,为程序中的每一个文件使用,当执行读文件的操作时,从磁盘文件将数据先读入内存缓冲区”,装满后再从内存“缓冲区”依此读入接收的变量。执行写文件的操作时,先将数据写入内存“缓冲区”,待内存“缓冲区”装满后再写入文件。由此可以看出,内存 “缓冲区”的大小,影响着实际操作外存的次数,内存“缓冲区”越大,则操作外存的次数就少,执行速度就快、...

kessity的博客 581

海康工业相机使用教程

海康工业相机连接电脑教程

qq_43251445的博客 2万+

QGIS v3.28 高效加载OSM在线地图的三种实用方法

本文详细介绍了在QGIS v3.28中高效加载OSM在线地图的三种实用方法:通过XYZ Tiles直接连接、使用QuickMapServices插件以及配置WMS/WTMS服务。针对每种方法提供了具体操作步骤、常见问题解决方案和性能优化建议,帮助用户根据需求选择最适合的方案,提升GIS工作效率。

weixin_29233333的博客 433

open()与fopen()函数

fopen(),open():打开一个文件用于读或写fopen()函数经常被我们使用 fopen()实例:    fopen(文件名, 使用文件的方式)FILE *fp;if((fp = fopen("file", "w")) ==  NULL)        //fopen()的返回值是一个指针    file为文件名   w:写 r:读 a:追加 {     print

yuesheng3707的专栏 1904

YOLOv4目标检测算法——通俗易懂的解析

YOLOv4目标检测算法——通俗易懂的解析

chase 7135

Linux编程基础——文件读写

缓冲I/O和非缓冲I/O 文件读写主要牵涉到了如下五个操作:打开、关闭、读、写、定位。在Linux系统中,提供了两套API,一套是C标准API:fopen、fclose、fread、fwrite、fseek,另一套则是POSIX定义的系统API:open、close、read、write、seek。 其中POSIX定义的API是系统API,而C标准API是基于系统API的封装,并且提供了额外...

weixin_34061042的博客 302

llama-factory微调qwen2.5-vl

使用llama-factory完成qwen2.5-vl微调

qq_44908396的博客 2932

FPGA DDR3实战(四):DDR地址映射自动化测试(1)—— 测试程序设计与代码逻辑

本文介绍了一种DDR地址映射自动化测试方案,旨在提高板卡调试效率。方案通过AXI4协议实现主从端通信,构建了包含地址控制器和测试数据生成器的模块化架构。测试程序支持突发传输、状态监控和错误检测,可灵活配置测试参数。采用状态机控制流程,先写入递增数据再读取比对,完成功能验证和性能评估。该方案可系统化验证DDR的正确性、稳定性和可靠性,相比传统手动测试显著提升效率。

FPGA_小田老师的博客 1976

Linux设备驱动中的阻塞和非阻塞I/O

【基本概念】 1、阻塞   阻塞操作是指在执行设备操作时,托不能获得资源,则挂起进程直到满足操作所需的条件后再进行操作。被挂起的进程进入休眠状态(不占用cpu资源),从调度器的运行队列转移到等待队列,直到条件满足。 2、非阻塞   非阻塞操作是指在进行设备操作是,若操作条件不满足并不会挂起,而是直接返回或重新查询(一直占用CPU资源)直到操作条件满足为止。   当用户空间的应用...

weixin_30549657的博客 255

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【Linux】五种IO模型 + 非阻塞IO

【Linux】非阻塞IO

tan_run的博客 1567

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

非阻塞IO

这是在打开文件时设置非阻塞的方式,如果要将已经打开的某个文件或套接字设置为非阻塞,此时就需要用到。

FBI_BAIGOU的博客 1344

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

非阻塞 IO

文章介绍了五种IO模型中的非阻塞IO实现方式。重点讲解了使用fcntl系统调用设置文件描述符为非阻塞模式的方法,包括获取当前标志位(F_GETFL)和设置非阻塞标志(O_NONBLOCK)的步骤。作者通过示例代码展示了如何将标准输入设置为非阻塞模式,并详细说明了非阻塞read的返回值处理:当n>0时表示成功读取,n=0表示输入结束,n<0时需要根据errno区分是真正出错(EINTR)还是数据未就绪(EAGAIN/EWOULDBLOCK)。该文为后续讲解select多路复用技术奠定了基础。

Small_entreprene的博客 852

Day21 文件IO 、 标准IO与文件IO的关系 \ 目录IO

rwx:创建该文件用户同组的用户对文件是否拥有读写执行的权限。从文件描述符中读取count个自己数据放入buf对应的空间。是系统调用,是Linux内核中的函数接口。fread/fwrite 二进制操作文件。O_CREAT 文件不存在就创建,需要传入第3个参数。rwx:创建该文件的用户对文件是否拥有读写执行的权限。将buf开始的count个字节写入文件描述符fd中。是库函数,是对文件IO的封装。rwx:其余人是否对文件拥有读写执行的权限。2. 读写文件 write/read。count:最多存放元素的个数。

m0_71562438的博客 1212

【Unix】文件IO与标准IO

一、文件IO 大多数UNIX文件IO只需用到5个函数:open、read、write、lseek以及close。 这些函数经常被称为不带缓存的IO(unbuffered IO),不带缓存是指每个read和write都调用内核中的一个系统调用。 这些不带缓存的IO函数不是ANSI C的组成部分,但是是POSIX.1和XPG3的组成部分。 1、对于内核而言,所有打开文件都由文件描述符引

guansir的专栏 3832

高效IO——五种IO模型概念和非阻塞IO

前言: 内存于外设进行数据交互叫做IO。 IO的过程中主要由两个动作,一个是等待,一个是拷贝。 比如: 读IO,就是在等待可以读数据的条件,条件成立将数据从内核空间拷贝到用户空间。 写IO,就是在等待可以写数据的条件,条件成立将数据从用户空间拷贝到内核空间。 高效IO的本质是:单位时间内,尽可能的减少等待的比重。 一.五种IO模型 阻塞IO:在内核数据准备好之前,系统调用会一直等待。 所有套接...

weixin_57023347的博客 1160

什么是阻塞IO和非阻塞IO

NIO是为了弥补传统IO的不足而诞生的,NIO也有缺点,因为NIO是面向缓冲区的操作,每一次的数据处理都是对缓冲区进行的,在数据处理之前必须要判断缓冲区的数据是否完整或者已经读取完毕,如果没有,假设只读取了一部分,那么对不完整的数据处理没有任何意义。NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率较高。:一个应用程序执行I/O操作时,会被阻塞,直到数据准备好或操作完成。应用程序发起一个 I/O 操作后,可以继续执行其他操作,当 I/O 操作完成时会通知应用程序。

m0_60469045的博客 1046

文件IO与标准库IO

文件IO与标准库IO一、文件(系统)IO与标准库IO二、标准IO 相关的API1.fopen / fcolse2.fread/fwrite/fseek/ftell3.fgetc/fgets fputc/fputs三、文件IO相关API1.open/close2.read/write3.lseek4.ioctl/fcntl四、进阶文件I/O1.独占方式创建文件2.向文件尾部追加数据 与非阻塞IO3.复制文件描述符4.在文件特定偏移量处的I/O:pread/pwrite5.分散输入和集中输出:readv/w

xiupong的博客 274

【Linux】五种 IO 模型:阻塞、非阻塞IO

五种 IO 模型:阻塞、非阻塞IO

2203_76003626的博客 1411

Linux 【C编程】IO进阶— 阻塞IO、非阻塞IO、 多路复用IO、 异步IO

本文主要讲了Linux的高级IO操作,阻塞IO与非阻塞IO,多路IO复用与异步IO

weixin_46999174的博客 1869

【linux】高级IO,认识五种IO模型,非阻塞IO的实现,fcntl

一、前置知识 二、五种IO模型 三、深入认识五种IO模型 阻塞IO 非阻塞IO 信号驱动IO 多路转接 异步IO 四、非阻塞IO的实现 fcntl

重铸自身根基的博客 1207

io探索-标准io和文件 io/io模式-阻塞和非阻塞

https://blog.youkuaiyun.com/yang2011079080010/article/details/53759759 https://blog.youkuaiyun.com/carolzhang8406/article/details/7227761 对于操作系统而言,I/O操作可以分为两类,一类是带缓存的IO,又称为标准IO(C标准库中提供了标准IO库,即stdio),它实现了跨平台的...

小豆角的博客 449

【Linux网络】五种IO模型与阻塞IO

💬 hello!各位铁子们大家好哇。今日更新了五种IO模型与阻塞IO的内容。

qinjh_的博客 2243
上一篇: 嵌入式学习笔记
下一篇: extern使用方法总结
zhouxf_cn
博客等级 码龄14年 54粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值