IO进程线程day3(2023.7.31)

这篇具有很好参考价值的文章主要介绍了IO进程线程day3(2023.7.31)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、Xmind整理:

IO进程线程day3(2023.7.31),算法

文件描述符概念:

IO进程线程day3(2023.7.31),算法

二、课上练习:

练习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;
}

IO进程线程day3(2023.7.31),算法

练习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+1
             int tm_year;   /* Year - 1900 */              年= tm_year+1900
             int 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;
}

IO进程线程day3(2023.7.31),算法

练习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;
}

IO进程线程day3(2023.7.31),算法

IO进程线程day3(2023.7.31),算法

练习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_TRUNC
 mode_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进行组合。

IO进程线程day3(2023.7.31),算法 

练习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的值修改成0
	umask(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;
}

IO进程线程day3(2023.7.31),算法

注意: 

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的值修改成0
	umask(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 0
	while(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位置
	}
#endif
	printf("读取完毕\n");
	if(close(fd)<0)
	{
		ERR_MSG("close");
		return -1;
	}
	printf("close success\n");

	return 0;
}

IO进程线程day3(2023.7.31),算法

 例题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;
}

IO进程线程day3(2023.7.31),算法

练习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;
}

IO进程线程day3(2023.7.31),算法

注意: 

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

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

练习11:获取文件属性

IO进程线程day3(2023.7.31),算法

练习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 */        用户的uid
 gid_t     st_gid;         /* Group ID of owner */       组用户的gid
 off_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]

IO进程线程day3(2023.7.31),算法

例题:文件权限提取 
#include <stdio.h>
#include <head.h>

void get_filePermission(mode_t m)   //mode_t m = buf.st_mode
{
    if((m & 0400) != 0)
        putchar('r');
    else
        putchar('-');

    if((m & 0200) != 0)                                      
        putchar('w');
    else
        putchar('-');

    if((m & 0100) != 0)
        putchar('x');
    else
        putchar('-');

    ///
    if((m & 0040) != 0)
        putchar('r');
    else
        putchar('-');

    if((m & 0020) != 0)
        putchar('w');
    else
        putchar('-');

    if((m & 0010) != 0)
        putchar('x');
    else
        putchar('-');
    

    if((m & 0004) != 0)
        putchar('r');
    else
        putchar('-');

    if((m & 0002) != 0)
        putchar('w');
    else
        putchar('-');

    if((m & 0001) != 0)
        putchar('x');
    else
        putchar('-');

    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;
}

IO进程线程day3(2023.7.31),算法

三、课后作业:

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;
}

IO进程线程day3(2023.7.31),算法

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');
		else
			putchar('-');
		x=x>>1;
		if((m & x) != 0)                                      
			putchar('w');
		else
			putchar('-');
		x=x>>1;
		if((m & x) != 0)
			putchar('x');
		else
			putchar('-');
		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;
}

IO进程线程day3(2023.7.31),算法文章来源地址https://www.toymoban.com/news/detail-621278.html

到了这里,关于IO进程线程day3(2023.7.31)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【趣学算法】Day3 贪心算法——背包问题

    14天阅读挑战赛 努力是为了不平庸~ 算法学习有些时候是枯燥的,这一次,让我们先人一步,趣学算法!  ❤️一名热爱Java的大一学生,希望与各位大佬共同学习进步❤️ 🧑个人主页:@周小末天天开心 各位大佬的点赞👍 收藏⭐ 关注✅,是本人学习的最大动力 感谢! 📕该

    2024年02月02日
    浏览(44)
  • IO 与进程线程

    2023年05月28日
    浏览(43)
  • 深度学习DAY3:神经网络训练常见算法概述

    这是最常见的神经网络训练方法之一。它通过计算损失函数对权重的梯度,并沿着梯度的反方向更新权重,从而逐步减小损失函数的值。梯度下降有多个变种,包括随机梯度下降(SGD)和小批量梯度下降。 反向传播是一种基于链式法则的方法,用于计算神经网络中每个神经元

    2024年02月07日
    浏览(45)
  • IO进程线程,文件IO(open),文件(stat)与目录(opendir)属性的读取

          一、文件IO 1、文件io通过系统调用来操作文件 系统调用:系统提供给用户的一组API(接口函数)         open/read/write/close/lseek... 用户空间进程访问内核的接口 把用户从底层的硬件编程中解放出来 极大的提高了系统的安全性 使用户程序具有可移植性(同一系统下) 是操作

    2024年02月11日
    浏览(35)
  • Day31- 贪心算法part05

    题目一:453. 无重叠区间  435. 无重叠区间 给定一个区间的集合  intervals  ,其中  intervals[i] = [starti, endi]  。返回  需要移除区间的最小数量,使剩余区间互不重叠  。 主要思想是优先保留结束时间早的区间,这样留给其他区间的空间就更多,从而减少需要移除的区间数量

    2024年01月19日
    浏览(44)
  • 【算法日志】贪心算法刷题:重叠区问题(day31)

    目录 前言 无重叠区间(筛选区间) 划分字母区间(切割区间)  合并区间 今日的重点是掌握重叠区问题。

    2024年02月12日
    浏览(48)
  • IO进程线程第五天(8.2)进程函数+XMind(守护进程(幽灵进程),输出一个时钟,终端输入quit时退出时钟)

    1.守护进程(幽灵进程) 2.输出一个时钟,终端输入quit时退出时钟        

    2024年02月14日
    浏览(49)
  • Day 31 C++ STL常用算法(下)

    copy——容器内指定范围的元素拷贝到另一容器中 函数原型 copy(iterator beg, iterator end, iterator dest); // 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置 // beg 开始迭代器 // end 结束迭代器 // dest 目标起始迭代器 注意——利用copy算法在拷贝时,目标容器要提前

    2024年02月12日
    浏览(40)
  • 代码随想录day31 贪心算法初探

            就像卡哥视频里说的一样,感觉贪心算法确实没什么固定的套路,唯一的思路就是求局部最优解然后推广到全局最优解,但是什么是局部最优解,这个需要慢慢做题来摸索总结,有点像调参,蛮玄学的,纯考脑子 假设你是一位很棒的家长,想要给你的孩子们一些

    2024年01月18日
    浏览(179)
  • IO进程线程,文件与目录,实现linux任意目录下ls -la

    注意文件的名字、路径是如何输入的。 函数opendir打开目录,struct dirent,struct stat这些结构体的含义。          readdir()函数是一个用于读取目录内容的系统调用或库函数,在类Unix操作系统中(如Linux)广泛使用。它用于遍历目录,并逐个获取目录中的条目(文件和子目录

    2024年02月10日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包