IO进程线程day3(2023.7.31)

一、Xmind整理:

文件描述符概念:

二、课上练习:

练习1:用fread和fwrite实现文件拷贝 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
int main(int argc, const char *argv[])
{//以读的方式打开源文件FILE* fp_r=fopen("./01_fopen.c","r");if(NULL==fp_r){ERR_MSG("fopen");return -1;}//以写的方式打开源文件FILE* fp_w=fopen("./copy.c","w");if(NULL==fp_w){ERR_MSG("fopen");return -1;}//读一次写一次,直到文件读取完毕char buf[128]="";size_t res=0;while(1){bzero(buf,sizeof(buf));//以128为单位,读取1个数据,所当不足128的时候//剩下的数据读取不出来,所以这个代码是错误的res=fread(buf,1,sizeof(buf),fp_r);printf("res=%ld\n",res);if(0==res)break;fwrite(buf,1,res,fp_w);}printf("拷贝完毕\n");//关闭fclose(fp_w);fclose(fp_r);return 0;
}

练习2:time

功能:从1970-1-1日至今的秒数

原型:

 #include <time.h>time_t time(time_t *tloc);

参数:

time_t *tloc:若不为空,则1970-1-1日至今的秒数同样会被存储到该指针指向的内存空间中;

返回值:

成功,返回1970-1-1日至今的秒数;
失败,返回((time_t) -1),更新errno;
time_t t = time(NULL);  
printf("%ld\n", t);
time_t pt;                     
time(&pt);
printf("%ld\n", pt);

练习3:localtime

功能:将1970-1-1日至今的秒数转换成日历格式

原型:

#include <time.h>
struct tm *localtime(const time_t *timep);

参数:

time_t *timep: 指定要转换成日历格式的秒数的首地址;

返回值:

成功,返回结构体指针;  vi -t tm可以查看struct tm 成员 或者man手册往下翻
失败,返回NULL;更新errno;      
struct tm {int tm_sec;    /* Seconds (0-60) */         秒int tm_min;    /* Minutes (0-59) */         分int tm_hour;   /* Hours (0-23) */           时int tm_mday;   /* Day of the month (1-31) */  日int tm_mon;    /* Month (0-11) */             月= tm_mon+1int tm_year;   /* Year - 1900 */              年= tm_year+1900int tm_wday;   /* Day of the week (0-6, Sunday = 0) */    星期int tm_yday;   /* Day in the year (0-365, 1 Jan = 0) */   一年中的第几天};

例题: 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <head.h>
int main(int argc, const char *argv[])
{/*time_t t=time(NULL);printf("%ld\n",t);time _t pt;time(&pt);printf("%d\n",pt);*/time_t t;struct tm* info=NULL;while(1){t=time(NULL);info=localtime(&t);printf("%d-%02d-%02d %02d:%02d:%02d\r",\info->tm_year+1900,info->tm_mon+1,info->tm_mday,\info->tm_hour,info->tm_min,info->tm_sec);fflush(stdout);sleep(1);}return 0;
}

练习4:文件描述符的总量

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
int main(int argc, const char *argv[])
{printf("%d %d %d\n",stdin->_fileno,stdout->_fileno,stderr->_fileno);FILE*fp=NULL;while(1){fp=fopen("./1.txt","w");if(NULL==fp){ERR_MSG("fopen");return -1;}printf("%d ",fp->_fileno);fflush(stdout);}return 0;
}

练习5:open

功能:打开一个文件

原型:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

参数:

 char *pathname:指定要打开的文件的路径和名字;int flags:打开方式O_RDONLY     只读, O_WRONLY     只写,O_RDWR       读写----以上三种必须包含一种----------O_APPEND     追加方式打开,O_TRUNC      清空,若文件存在,且是一个普通文件,且以写的方式打开O_CREAT      若文件不存在,则创建一个普通文件。若有多个选项合成一个打开方式,则用按位或连接:"w":O_WRONLY | O_CREAT | O_TRUNCmode_t mode:用来指定文件创建的时候的权限,例如:0664若flags中包含了O_CREAT或者O_TMPFILE的时候,就必须写mode参数;若flags没有O_CREAT或者O_TMPFILE的时候,会忽略mode参数;

返回值:

成功,返回文件描述符,
失败,返回-1,更新errno;

注意:

标准IO中的 r r+ w w+ a a+,用文件IO中的flags进行组合。

 

练习6:umask

the mode of the created file is (mode & ~umask).

文件创建时候的真实权限是 mode & ~umask

mode: 0777 -> 111 111 111 umask?111 111 101=> ~umask -> umask = 000 000 010 = 0002

结果: 0775 ----> 111 111 101

i. umask是什么

文件权限掩码,目的就是影响文件创建时候的权限。可以通过设置umask的值保证某些用户肯定没有某些权限。

ii. 获取umask的值

终端输入:umask

iii. 修改umask的值

1.终端输入: umask 0 只在设置终端有效

2.umask()函数

 #include <sys/types.h>#include <sys/stat.h>mode_t umask(mode_t mask);umask(0);

练习7:close

功能:关闭文件; 释放文件描述符

原型:

#include <unistd.h>
int close(int fd);

参数:

int fd:指定要关闭的文件描述符;

返回值:

成功,返回0;
失败,返回-1,更新errno;

练习8:write

功能:将数据写入到文件中

原型:

 #include <unistd.h>ssize_t write(int fd, const void *buf, size_t count);

参数:

int fd:指定要将数据写入到哪个文件中,填对应的文件描述符;
void *buf:指定要输出的数据的首地址,可以是任意类型数据;
size_t count:指定要输出的数据字节数;

返回值:

成功,返回成功输出的字节数;
失败,返回-1,更新errno;

 例题: 创建一个权限是0777的文件,并在数据写入到文件中

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
int main(int argc, const char *argv[])
{//将本程序的umask的值修改成0umask(0);int fd=open("./open.txt",O_WRONLY|O_CREAT|O_TRUNC,0777);if(fd<0){ERR_MSG("open");return -1;}printf("open success\n");ssize_t res=0;char buf[]="hello world";res=write(fd,buf,sizeof(buf));printf("res=%ld\n",res);if(close(fd)<0){ERR_MSG("close");return -1;}printf("close success\n");return 0;
}

注意: 

write函数指定写多少个字节,就会从内存中拿多少个字节,写入到文件中,即使越界

练习9:read

功能:从文件中读取数据

原型:

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

参数:

int fd:指定要从哪个文件中读取数据,填对应的文件描述符;
void *buf:指定要将读取到的数据存储到那块空间中,可以是任意类型数据;
size_t count:指定要读取的数据字节数;

返回值:

 >0, 成功,返回成功读取的字节数;=0, 文件读取完毕;=-1, 失败,返回-1,更新errno;

 例题1: read的使用

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
int main(int argc, const char *argv[])
{//将本程序的umask的值修改成0umask(0);int fd=open("./01_fileno.c",O_RDONLY);if(fd<0){ERR_MSG("open");return -1;}printf("open success\n");ssize_t res=0;char buf[128]="";while(1){bzero(buf,sizeof(buf));res=read(fd,buf,sizeof(buf));if(0==res){break;}//将数据写到终端,写的个数为实际读取到的字节数write(1,buf,res);}#if 0while(1){bzero(buf,sizeof(buf));/***************************************///由于后续打印的是使用%s打印,所以需要保留一个\0位置//防止%s打印的时候越界少\0位 res=read(fd,buf,sizeof(buf)-1);if(0==res){break;}printf("%s",buf);    //%s打印直到遇到\0位置}
#endifprintf("读取完毕\n");if(close(fd)<0){ERR_MSG("close");return -1;}printf("close success\n");return 0;
}

 例题2:用read和write函数实现,拷贝图片

 提示:1.ls-l查看图片类型

            2.eog  图片--->打开图片

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
int main(int argc, const char *argv[])
{//以读的方式打开源文件int fd_r=open("./1.png",O_RDONLY);if(fd_r<0){ERR_MSG("open");return -1;}printf("open success\n");//以写的方式打开目标文件int fd_w=open("./2.png",O_WRONLY|O_CREAT|O_TRUNC,0664);if(fd_w<0){ERR_MSG("open");return -1;}ssize_t res=0;char buf[128]="";//读一次写一次while(1){bzero(buf,sizeof(buf));res=read(fd_r,buf,sizeof(buf));if(0==res){break;}//读多少个就写多少个if(write(fd_w,buf,res)<0){ERR_MSG("write");return -1;}}printf("拷贝完成\n");//关闭if(close(fd_r)<0){ERR_MSG("close");return -1;}if(close(fd_w)<0){ERR_MSG("close");return -1;}printf("close success\n");return 0;
}

练习10:lseek

功能:修改文件偏移量

原型:

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);

参数:

int fd:文件描述符;
off_t offset: 距离whence参数指定的偏移量。往前偏移填负数, 往后偏移填正数
int whence:SEEK_SET,  文件开头位置SEEK_CUR,  文件当前位置SEEK_END   文件结尾位置

返回值:

成功,修改偏移量后,文件当前位置距离文件开头的偏移量;
失败,返回-1,更新errno;    
//计算文件大小
off_t size = lseek(fd_r, 0, SEEK_END);
printf("size=%ld\n", size);

例题:lseek的使用 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
int main(int argc, const char *argv[])
{//以读的方式打开源文件int fd_r=open("./1.png",O_RDONLY);if(fd_r<0){ERR_MSG("open");return -1;}//计算文件大小off_t size=lseek(fd_r,0,SEEK_END);printf("size=%ld\n",size);//关闭close(fd_r);return 0;
}

注意: 

若偏移量在文件开头,能否继续往前偏移 ---> 不行

若偏移量在文件结尾,能否继续往后偏移 ---> 可以

练习11:获取文件属性

练习12:stat

功能:获取文件的属性

原型:

 #include <sys/types.h>#include <sys/stat.h>#include <unistd.h>int stat(const char *pathname, struct stat *statbuf);

参数:

char *pathname:指定要获取属性的文件路径以及名字;
struct stat *statbuf:存储获取到的属性;

返回值:

成功,返回0;
失败,返回-1,更新errno;vi -t stat 或者 man手册往下翻
struct stat 
{ino_t     st_ino;         /* Inode number */            inode号mode_t    st_mode;        /* File type and mode */      文件类型和权限nlink_t   st_nlink;       /* Number of hard links */    硬链接数uid_t     st_uid;         /* User ID of owner */        用户的uidgid_t     st_gid;         /* Group ID of owner */       组用户的gidoff_t     st_size;        /* Total size, in bytes */    文件大小struct timespec st_atim;  /* Time of last access */         最后一次被访问的时间struct timespec st_mtim;  /* Time of last modification */   最后一次被修改的时间struct timespec st_ctim;  /* Time of last status change */  最后一次改变状态的时间#define st_atime st_atim.tv_sec      /* Backward compatibility */#define st_mtime st_mtim.tv_sec#define st_ctime st_ctim.tv_sec
};

提取文件的权限:

mode_t st_mode 本质上是一个unsigned int类型,里面存储了文件的类型和权限。

st_mode中其中低9bits存储了文件的权限:[0bit - 8bit]

例题:文件权限提取 

#include <stdio.h>
#include <head.h>void get_filePermission(mode_t m)   //mode_t m = buf.st_mode
{if((m & 0400) != 0)putchar('r');elseputchar('-');if((m & 0200) != 0)                                      putchar('w');elseputchar('-');if((m & 0100) != 0)putchar('x');elseputchar('-');///if((m & 0040) != 0)putchar('r');elseputchar('-');if((m & 0020) != 0)putchar('w');elseputchar('-');if((m & 0010) != 0)putchar('x');elseputchar('-');if((m & 0004) != 0)putchar('r');elseputchar('-');if((m & 0002) != 0)putchar('w');elseputchar('-');if((m & 0001) != 0)putchar('x');elseputchar('-');return;
}
int main(int argc, const char *argv[])
{struct stat buf;if(stat("./01_fileno.c", &buf) < 0){ERR_MSG("stat");return -1;}//文件的类型和权限printf("mode: 0%o\n", buf.st_mode);get_filePermission(buf.st_mode);//文件的硬链接数printf("link: %ld\n", buf.st_nlink);//文件的所属用户printf("uid: %d\n", buf.st_uid);//文件所属组用户printf("gid: %d\n", buf.st_gid);//文件大小printf("size: %ld\n", buf.st_size);//文件的修改时间printf("time: %ld\n", buf.st_ctime);//文件的名字return 0;
}

三、课后作业:

1.用read函数计算文件的大小 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
int main(int argc, const char *argv[])
{int fd = open("./1.png",O_RDONLY);if(fd < 0){ERR_MSG("open");return -1;}printf("open success\n");off_t size = lseek(fd,0,SEEK_END);printf("size=%ld\n",size);char c;ssize_t res = 0;int count = 0;lseek(fd,0,SEEK_SET);while(1){res = read(fd,&c,1);if(0 == res)break;count++;}printf("count=%d\n",count);if(close(fd) < 0){ERR_MSG("close");return -1;}printf("close success\n");return 0;
}

2.将课上的文件权限提取修改成循环方式

#include <stdio.h>
#include <head.h>void get_filePermission(mode_t m)
{long x=0400;char c[]="rwx";int count=0;while(x){if((m & x) != 0)putchar('r');elseputchar('-');x=x>>1;if((m & x) != 0)                                      putchar('w');elseputchar('-');x=x>>1;if((m & x) != 0)putchar('x');elseputchar('-');x=x>>1;}return;
}
int main(int argc, const char *argv[])
{struct stat buf;if(stat("./01_fileno.c", &buf) < 0){ERR_MSG("stat");return -1;}//文件的类型和权限printf("mode: 0%o\n", buf.st_mode);get_filePermission(buf.st_mode);//文件的硬链接数printf("link: %ld\n", buf.st_nlink);//文件的所属用户printf("uid: %d\n", buf.st_uid);//文件所属组用户printf("gid: %d\n", buf.st_gid);//文件大小printf("size: %ld\n", buf.st_size);//文件的修改时间printf("time: %ld\n", buf.st_ctime);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/16138.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么叫前后端分离?为什么需要前后端问题?解决了什么问题?

单体架构出现的问题 引出&#xff1a;来看一个单体项目架构的结构 通过上述可以看到单体架构主要存在以下几点问题&#xff1a; 开发人员同时负责前端和后端代码开发&#xff0c;分工不明确开发效率低前后端代码混合在一个工程中&#xff0c;不便于管理对开发人员要求高(既会前…

千元内合板和单板吉他怎么选?SAGA萨伽SF600和VEAZEN费森CLR300怎么样?哪一款更适合初学者入门使用!【吉他评测】

对于预算不多的朋友&#xff0c;在选购前翻阅查询很多资料&#xff0c;吉他材质、桶型和尺寸等等疑问&#xff0c;不知道怎么选&#xff0c;无从下手&#xff0c;还容易遇到烧火棍&#xff0c;在这里介绍这两款VEAZEN费森CLR300&#xff08;单板&#xff09;和SAGA萨伽SF600&am…

vuejs源码阅读之代码生成器

代码生成器是模版编译的最后以后&#xff0c;它的作用是将AST转换成渲染函数中的内容&#xff0c;这个内容可以称为代码字符串。 代码字符串可以被包装在函数中执行&#xff0c;这个函数就是我们通常说的渲染函数。 渲染函数被执行之后&#xff0c;可以生成一份VNode&#xf…

分治法 Divide and Conquer

1.分治法 分治法&#xff08;Divide and Conquer&#xff09;是一种常见的算法设计思想&#xff0c;它将一个大问题分解成若干个子问题&#xff0c;递归地解决每个子问题&#xff0c;最后将子问题的解合并起来得到整个问题的解。分治法通常包含三个步骤&#xff1a; 1. Divid…

【Python系列】Python基础语法轻松入门—从变量到循环

目录 写在前面 语法介绍 变量 数据类型 整数 浮点数 字符串 列表 元组 字典 运算符 算术运算符 比较运算符 逻辑运算符 条件语句 循环语句 图书推荐 图书介绍 参与方式 中奖名单 写在前面 Python 是一种高级、解释型的编程语言&#xff0c;具有简单易学…

华为数通HCIP-IGMP(网络组管理协议)

IGMP&#xff08;网络组管理协议&#xff09; 作用&#xff1a;维护、管理最后一跳路由器以及组播接收者之间的关系&#xff1b; 应用&#xff1a;最后一跳路由器以及组播接收者之间&#xff1b; 原理&#xff1a;当组播接收者需要接收某个组别的流量时&#xff0c;会向最后…

Yolov8新版本解读:优化点如何加入新版本,通过加入EMA注意力进行对比说明

本文目的: 最近yolov8进行了一次较大的更新,对一些优化点加在哪个位置上有些变动,因此本文主要通过具体案列进行对比和说明,以便在新版本上能够轻松上手。 老版本 ultralytics/nn 新版本更新为: modules文件夹下内容如下: 解读: 将modules.py拆分为 1.__init__.…

7.31--Day01实战单体项目苍穹外卖

总结 今天回来在高铁上构想了一下&#xff0c;感觉大二有很多的事情要做&#xff0c;这个暑假还有一个月不能浪费了&#xff0c;回来最重要的事情就是看病了&#xff0c;身体一定要调养好了&#xff0c;大二的规划&#xff0c;大二上继续做省大创&#xff0c;需要做的有软件开…

vue表单筛选

目录 筛选 HTML scss* filterComp 排序 表格 自定义数据样式 inner-table 分页 删除 default-modal 自定义元素的插槽-占位符 .search-wrap {height: 60px;display: flex;align-items: center;overflow: hidden;padding: 0 20px;.selected-options-wrap {flex: 1;.…

centos7安装mysql数据库详细教程及常见问题解决

mysql数据库详细安装步骤 1.在root身份下输入执行命令&#xff1a; yum -y update 2.检查是否已经安装MySQL&#xff0c;输入以下命令并执行&#xff1a; mysql -v 如出现-bash: mysql: command not found 则说明没有安装mysql 也可以输入rpm -qa | grep -i mysql 查看是否已…

如何监控系统的运行的状况

问题提出&#xff1a; 系统状态不稳定&#xff0c;需要排查原因&#xff0c;所以需要监视所有进程的资源&#xff0c;以及进程是那个程序&#xff08;有些进程名写的一样&#xff0c;需要根据PID查看是哪个执行文件&#xff09; 方法&#xff1a; 1. 使用subprocess函数&…

java基础复习(第二日)

java基础复习(二) 1.抽象的&#xff08;abstract&#xff09;方法是否可同时是静态的&#xff08;static&#xff09;&#xff0c;是否可同时是本地方法&#xff08;native&#xff09;&#xff0c;是否可同时被 synchronized修饰&#xff1f; 都不能。 抽象方法需要子类重写…

YOLOv8目标检测代码如何实现训练、测试、调用摄像头实时检测和追踪的接口调用脚本

实现训练、测试、调用摄像头实时检测和追踪的接口调用脚本 目录 介绍训练模型图片测试视频流测试目标跟踪结论 介绍 YOLOv8是单阶段目标检测的集大成之作&#xff0c;它可以帮助我们在图像或视频中自动识别和定位感兴趣的目标物体。本文将介绍如何调用YOLOv8的API实现训练、…

mysql的json处理

写在前面 需要注意&#xff0c;5.7以上版本才支持&#xff0c;但如果是生产环境需要使用的话&#xff0c;尽量使用8.0版本&#xff0c;因为8.0版本对json处理做了比较大的性能优化。你你可以使用select version();来查看版本信息。 本文看下MySQL的json处理。在正式开始让我们先…

第三篇-Tesla P40+CentOS7+CUDA 11.7 部署实践

硬件环境 系统&#xff1a;CentOS-7 CPU: 14C28T 显卡&#xff1a;Tesla P40 24G 准备安装 驱动: 515 CUDA: 11.7 cuDNN: 8.9.2.26 安装依赖 yum clean all yum update yum install -y gcc gcc-c pciutils kernel-devel-$(uname -r) kernel-headers-$(uname -r)查看GPU信息…

元类的认识和基础用法

元类 “元类就是深度的魔法&#xff0c;99%的⽤户应该根本不必为此操⼼。 如果你想搞清楚 究竟是否需要⽤到元类&#xff0c;那么你就不需要它。 那些实际⽤到元类的⼈都⾮常 清楚地知道他们需要做什么&#xff0c;⽽且根本不需要解释为什么要⽤元类。“——蒂姆彼得斯TimPeter…

PostgreSQL数据库中,查询时提示表不存在的解决办法

最近遇到一个奇怪的问题&#xff0c;以前从来没有遇到过&#xff0c;在postgres SCHEMA下执行select * from table1语句时&#xff0c;提示表不存在&#xff0c;而实际这个表确是存在的&#xff0c;只不过是在public SCHEMA下。在public SCHEMA下执行这个sql语句是没有问题的。…

【Linux下6818开发板(ARM)】在液晶屏上显示RGB颜色和BMP图片

(꒪ꇴ꒪ ),hello我是祐言博客主页&#xff1a;C语言基础,Linux基础,软件配置领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff01;送给读者的一句鸡汤&#x1f914;&#xff1a;集中起来的意志可以击穿顽石!作者水平很有限&#xff0c;如果发现错误&#x…

C++ 类和对象

面向过程/面向对象 C语言是面向过程&#xff0c;关注过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题 C是基于面对对象的&#xff0c;关注的是对象——将一件事拆分成不同的对象&#xff0c;依靠对象之间的交互完成 引入 C语言中结构体只能定义…

flask处理表单数据

flask处理表单数据 处理表单数据在任何 web 应用开发中都是一个常见的需求。在 Flask 中&#xff0c;你可以使用 request 对象来获取通过 HTTP 请求发送的数据。对于 POST 请求&#xff0c;可以通过 request.form 访问表单数据。例如&#xff1a; from flask import Flask, r…