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 查看是否已…

mysql的json处理

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

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…

IDEA中连接虚拟机 管理Docker

IDEA中连接虚拟机 管理Docker &#x1f4d4; 千寻简笔记介绍 千寻简笔记已开源&#xff0c;Gitee与GitHub搜索chihiro-notes&#xff0c;包含笔记源文件.md&#xff0c;以及PDF版本方便阅读&#xff0c;且是用了精美主题&#xff0c;阅读体验更佳&#xff0c;如果文章对你有帮…

【点云处理教程】00计算机视觉的Open3D简介

一、说明 Open3D 是一个开源库&#xff0c;使开发人员能够处理 3D 数据。它提供了一组用于 3D 数据处理、可视化和机器学习任务的工具。该库支持各种数据格式&#xff0c;例如 .ply、.obj、.stl 和 .xyz&#xff0c;并允许用户创建自定义数据结构并在程序中访问它们。 Open3D 广…

KafKa脚本操作

所有操作位于/usr/local/kafka_2.12-3.5.1/bin。 rootubuntu2203:/usr/local/kafka_2.12-3.5.1/bin# pwd /usr/local/kafka_2.12-3.5.1/bin rootubuntu2203:/usr/local/kafka_2.12-3.5.1/bin# ls connect-distributed.sh kafka-delegation-tokens.sh kafka-mirror-mak…

15. Spring AOP 的实现原理 代理模式

目录 1. 代理模式 2. 静态代理 3. 动态代理 3.1 JDK 动态代理 3.2 CGLIB 动态代理 4. JDK 动态代理和 CGLIB 动态代理对比 5. Spring代理选择 6. Spring AOP 实现原理 6.1 织入 7. JDK 动态代理实现 8. CGLIB 动态代理实现 9. 总结 1. 代理模式 代理模式&#xf…

Mac查看系统状态

syatem profiler mac系统中提供了system profiler来查看系统的详细信息&#xff0c;包括硬件、网络以及安装的软件 Console 显示了系统上的日志文件信息&#xff0c;有助于诊断问题 Activity Monitor 可以提供正在运行的系统的相关信息 https://zhhll.icu/2021/Mac/查看系统…