Linux系统编程学习--第3天标准IO非缓冲区文件操作及时间编程

非缓冲的文件操作访问方式,每次对文件进行一次读写操作时,都需要使用读写系统调用来处理此操作,即需要执行一次系统调用,执行一次系统调用将涉及到CPU状态的切换,即从用户空间切换到内核空间,实现进程上下文的切换,这将损耗一定的CPU时间,频繁的磁盘访问对程序的执行效率造成很大的影响

非缓冲区的文件操作就是每一次读写操作都要横跨内核层和应用层,没有缓冲区,实时性更高。

接口函数
1、open非缓冲区打开文件函数

函数原型:
int open(const char *pathname, int flags); 
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode); 
函数功能:打开文件
函数参数:pathname:打开文件的路径、flag打开方式,打开方式有以下这些,他们可以用|一同使用,比如我要以读写的方式打开文件1.txt,当文件不存在时创建文件,文件的权限给mode&~umask(umask是一个固定数可以在中断输入umask来查看)。mode:权限,配合O_CREAT使用
函数返回值:成功返回文件描述符,失败返回-1

umask查看
在这里插入图片描述
打开方式
在这里插入图片描述
演示
代码

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char* args[])
{
	int i=open("./2345",O_RDWR|O_CREAT|O_TRUNC,0777);
	if(i!=-1)
	{
		printf("打开文件成功\n");
		
	}
	close(i);
}

结果多出了一个名为2345的文件权限为0775
在这里插入图片描述
2、close

函数原型:void close(int fd);
函数功能:关闭文件
函数参数:fd:文件描述符
函数返回值:关闭成功返回0,失败则返回-1.

3、非缓冲区的读函数read

函数原型:ssize_t read(int fd, void *buf, size_t count);
函数功能:读文件内容到buf
函数参数:
fd:文件描述符
buf:要读入的缓冲区, 提前申请好的
count:要读入的字节数
函数返回值:成功返回:实际读的字节数,失败返回 -1

演示
2345文本中的内容:
在这里插入图片描述
代码读取五个字符

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char* args[])
{
	int i=open("./2345",O_RDWR|O_CREAT,0777);
	if(i!=-1)
	{
		printf("打开文件成功\n");
		char buf[20];
		if(read(i,buf,5)!=-1)
		{
			printf("读取:%s\n",buf);
		}
	}
	close(i);
}

结果在这里插入图片描述

4、非缓冲区的写函数write

函数原型:ssize_t write(int fd, const void *buf, size_t count);
函数功能:将buf内容写入文件。
函数参数:
fd:文件描述符
buf:要读入的缓冲区, 提前申请好的
count:要读入的字节数
函数返回值:成功返回:实际读的字节数,失败返回 -1

演示写入2345文本”helloworld“

#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* args[])
{
	int i=open("./2345",O_RDWR|O_CREAT,0777);
	if(i!=-1)
	{
		printf("打开文件成功\n");
		char buf[20]="hello world!!";
		if(write(i,buf,14)!=-1)
		{
			printf("写入成功\n");
		}
	}
	close(i);
}

在这里插入图片描述
使用vi编辑器查看2345内容
在这里插入图片描述
5、指针移动函数
在这里插入图片描述

时间编程

与时间有关的shell命令
在中断输入命令即可查看对应时间
在这里插入图片描述
先来看两个数据类型

typedef long time_t;

解释:将long类型重定义为time_t,time_t用来存储从1970年到当前时间的秒数

结构体tm

struct tm {
int tm_sec; /* 秒:取值区间为[0,59] /
int tm_min; /
分:取值区间为[0,59] /
int tm_hour; /
时:取值区间为[0,23] /
int tm_mday; /
一个月中的日期:取值区间为[1,31] /
int tm_mon; /
月份(从一月开始, 0 代表一月) :取值区间为[0,11] /
int tm_year; /
年份:其值等于实际年份加上 1900*/
int tm_wday; /* 星期:取值区间为[0,6],其中 0 代表星期天,1 代表星期一,以此类推 /
int tm_yday; /
从每年的 1 月 1 日开始的天数:取值区间为[0,365],其中 0 代表 1 月 1 日,1 代表 1 月 2 日,以此类推*/
int tm_isdst; /* 夏令时标识符,实行夏令时的时候,tm_isdst 为正,不实 行夏令时的进候, tm_isdst 为 0;不了解情况时, tm_isdst()为负*/
};
这个结构体可以存储年月日时分秒等时间,看起来更加直观。那么这两个数据类型有什么用呢?
在编程中可以这样用
1、time函数

函数原型:time_t time(time_t *t);
函数功能:返回从1970年到现在的秒数,并且将其存储在t中
函数参数:time_t变量的地址,你需要定义一个time_t的变量
函数返回值:成功返回日历时间,失败返回-1

演示
代码

#include <stdio.h>
#include <time.h>
int main(int argc,char* args[])
{
	time_t s;
	if(time(&s)!=-1)
	{
		printf("%ld\n",s);
	}
	
}

现象
在这里插入图片描述
将1704453503转化为年得到54年
在这里插入图片描述
这个秒数不太直观如果能转化为上面tm的结构体就好了。
2、gmtime

函数原型:struct tm *gmtime(const time_t *timep);
函数功能:将1970年到现在的秒数转化为tm结构体类型
函数参数:你需要转化的time_t类型的数据
函数返回值:成功返回结构体指针gmtime,失败返回NULL

我们将刚才的秒数转化为tm结构体
代码

#include <stdio.h>
#include <time.h>
int main(int argc,char* args[])
{
	struct tm *ss=NULL;
	time_t s;
	if(time(&s)!=-1)
	{
		printf("%ld\n",s);
	}
	if((ss=gmtime(&s))!=NULL)
	{
		printf("转化成功\n");
		//hour需要加上8,因为我们是东八区
		printf("%d年%d月%d日%d时%d分%d秒\n",ss->tm_year+1900,ss->tm_mon+1,ss->tm_mday,ss->tm_hour+8,ss->tm_min,ss->tm_sec);
	}
}

现象
在这里插入图片描述
3、localtime
这个函数和gmtime函数唯一的区别是localtime用的是你虚拟机的时间

4、asctime

函数原型: char *asctime(const struct tm *tm);
函数功能:将struct tm格式的时间转化为字符串
函数参数:带转化的tm格式的时间
函数返回值:成功返回字符串显示的时间,失败返回NULL

把tm结构体转化为字符串显示
演示
代码

#include <stdio.h>
#include <time.h>
int main(int argc,char* args[])
{
	struct tm *ss=NULL;
	time_t s;
	if(time(&s)!=-1)//得到1970年到当前时间的秒数
	{
		printf("%ld\n",s);
	}
	if((ss=gmtime(&s))!=NULL)//将秒数转化为tm结构体类型
	{
		printf("转化成功\n");
		printf("%s\n",asctime(ss));//将tm结构体转化为字符串,注意没有加东八区的那八个小时
	}
}

现象
在这里插入图片描述
5、ctime将日历时间(秒数)转化为本地时间

函数原型: char *ctime(const time_t *timep);
函数功能:将日历时间转化为本地时间
函数参数:待转化为日历时间
函数返回值:成功返回一字符串表示目前当地的时间日期。,失败返回NULL

演示
将1970年距现在时间的秒数转化为字符串
代码

#include <stdio.h>
#include <time.h>
int main(int argc,char* args[])
{
	time_t s;
	if(time(&s)!=-1)//得到1970年到当前时间的秒数
	{
		printf("%ld\n",s);
	}
	printf("%s\n",ctime(&s));
}

现象
在这里插入图片描述
6、strftime这个方法可以让tm结构体转化为任意格式的字符串。
比如我要把时间转化为2024/1/5 20:34

函数原型: size_t strftime(char *s, size_t max, const char *format, const struct tm *tm)
函数功能:将struct tm格式的时间按照对应格式转化为字符串
函数参数:char*s:转化好的字符串存储在里面,max:复制到s的最大字节数,format:格式,要转化的tm结构体
函数返回值:写入s内容的大小,失败返回0

format格式参照下面的表
在这里插入图片描述
演示:将时间转化为"2024/1/5 20:34"的格式
代码

#include <stdio.h>
#include <time.h>
int main(int argc,char* args[])
{
	char tt[50];
	struct tm *ss=NULL;
	time_t s;
	if(time(&s)!=-1)//得到1970年到当前时间的秒数
	{
		printf("%ld\n",s);
	}
	ss=gmtime(&s);//将秒数转化为结构体
	ss->tm_hour+=8;//加上东八区那八个小时
	if(strftime(tt,50,"%Y/%m/%d %H:%M",ss)!=0)
	{
		printf("%s\n",tt);
	}
}

结果
在这里插入图片描述

  • 25
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值