标准IO函数和文件IO函数的学习

文章介绍了Unix/Linux系统中关于时间管理的函数,如time()和localtime(),以及文件I/O操作,包括文件描述符的概念、open()、close()、read()、write()、lseek()等函数的使用,并提供了计算文件大小和查看文件属性的示例代码。
摘要由CSDN通过智能技术生成

时间相关的函数

time

  • 功能:从1970-1-1日至今的秒数
  • 原型:time_t time(time_t *tloc)
  • 参数:time_t time(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);

localtime

  • 功能:将1970-1-1日至今的秒数转换成日历格式
  • 原型: struct tm *localtime(const time_t *timep)
  • 参数:time_t *timep:指定要转换成日历格式的秒数的首地址
  • 返回值:成功,返回结构体指针;失败,返回ULL,更新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) */   一年中的第几天

           };

文件IO函数

文件秒数符

概念

  • 尝试打开一个文件的时候,系统就会自动给这个文件分配一个编号,用这个编号来描述这个文件。这个编号就是文件描述符。
  • 文件描述符的性质:和数组下标类似,在main函数启动前,操作系统会帮助我们在用户空间创建一个数组(文件描述符表),且容量默认为1024,范围是【0,1023】
  • 文件描述符申请原则:从小到大依次遍历,直到遇到没有被使用的文件描述符
    在这里插入图片描述

特殊的文件描述符

特殊的流指针特殊的文件描述符
FILE *stdinstdin->fileno0
FILE *stdoutstdout->fileno1
FILE *stderrstderr->fileno2

文件描述符的总量

默认是1024个

  • 循环打开不关闭,直到超出打开上限,得到文件描述符总量
  • getdtablesize():获取操作系统的文件描述符总量(printf"%d\n",getdtablesize());

文件IO的函数

open

  • 功能:打开一个文件

  • 原型:

    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------->若文件不存在,则创建一个普通文件
    注意:若有多个选项合成一个打开方式,则用按位或连接
    mode_t mode:用来指定文件创建时候的权限
    若flags中包含了O_CREAT或者O_TMPFILE的时候,就必须写mode参数
    若flags没有O_CREAT或者O_TMPFILE的时候,会忽略mode参数

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

umask

  • umask:文件权限掩码,目的就是影响文件创建时候的权限。可以通过设置umask的值保证某些用户肯定没有某些权限
    获取umask的值:终端输入:umask
    修改umask的值
    1>终端输入:umask 0(只在设置终端有效)
    2>umask()函数

close

  • 功能:关闭文件;释放文件描述符
  • 原型:int close(int fd)
  • 参数:int fd:指定要关闭的文件描述符
  • 返回值:返回,返回0;失败,返回-1,更新errno

write

  • 功能:将数据写入到文件中
  • 原型:ssize_t write(int fd, const void *buf, size_t count)
  • 参数:int fd:指定要将数据写入到哪个文件中,填对应的文件描述符;
    void *buf:指定要输出的数据的首地址,可以是任意类型;
    size_t count:指定要输出的数据字节数;
    返回值:成功,返回成功输出的字节数;失败,返回-1,更新errno

read

  • 功能:从文件中读取数据;

  • 原型: ssize_t read(int fd, void *buf, size_t count)

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

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

lseek

  • 功能:修改文件偏移量

  • 原型: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);

注意:
若偏移量在文件开头,不能继续往前偏移
若偏移量在文件结尾,能继续往后偏移

获取文件属性

stat

  • 功能:获取文件的属性
  • 原型:int stat(const char *pathname, struct stat *statbuf)
  • 参数:char *pathname:指定要获取属性的文件路径以及名字;
    struct stat *statbuf:存储获取到的属性;
    返回值:成功,返回0;失败,返回-1,更新errno

作业

一、用read函数完成文件大小计算

#include <head.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
	int fp_r = open("/home/ubuntu/图片/1.png",O_RDONLY);
	if(fp_r < 0)
	{
		ERRO_MES("open");
		return -1;
	}
	off_t size=lseek(fp_r,0,SEEK_END);
	printf("size = %ld\n",size);
	lseek(fp_r,0,SEEK_SET);
	off_t count=0;
	char c=0;
	ssize_t res = 0;
	while(1)
	{
		res = read(fp_r,&c,1);
		if(res == 0)
			break;
		count++;
	}
	printf("count = %ld\n",count);
	close(fp_r);

	return 0;
}

二、将文件权限提取修改成循环方式

#include <head.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
void get_filePermission(mode_t m)
{
	for(int i=0;i<9;i++)
	{
		if( (m & (0400>>i)) == 0)
		{
			putchar('-');
			continue;
		}
		switch(i%3)
		{
		case 0:putchar('r');break;
		case 1:putchar('w');break;
		case 2:putchar('x');break;
		}
	}
	return;
}
void get_fileType(mode_t m)
{
	if(S_ISREG(m))
		putchar('-');
	else if(S_ISDIR(m))
		putchar('d');
	else if(S_ISCHR(m))
		putchar('c');
	else if(S_ISBLK(m))
		putchar('b');
	else if(S_ISFIFO(m))
		putchar('p');
	else if(S_ISLNK(m))
		putchar('l');
	else if(S_ISSOCK(m))
		putchar('s');
}
int main(int argc, const char *argv[])
{
	struct stat buf;
	struct tm *info = NULL;
	if(stat("./stat.txt",&buf) < 0)
	{
		ERRO_MES("stat");
		return -1;
	}
//	printf("mode: 0%o\n",buf.st_mode);
	get_fileType(buf.st_mode);
	get_filePermission(buf.st_mode);
//	puts("");

	//文件的硬链接数
	printf(" %ld",buf.st_nlink);

	//文件的所属用户
//	printf(" %d",buf.st_uid);
	struct passwd *pwd=getpwuid(buf.st_uid);
	if(NULL == pwd)
	{
		ERRO_MES("getpwuid");
		return -1;
	}
	printf(" %s",pwd->pw_name);
	//文件所属组用户
//	printf(" %d",buf.st_gid);
	struct group *grp=getgrgid(buf.st_gid);
	if(NULL == grp)
	{
		ERRO_MES("getgrgid");
		return -1;
	}
	printf(" %s",grp->gr_name);
	//文件大小
	printf(" %ld",buf.st_size);

	//文件的修改时间
	info=localtime(&buf.st_ctime);
	printf(" %d月 %d %02d:%02d",info->tm_mon+1,\
			info->tm_mday,info->tm_hour,info->tm_min);
	printf(" stat.txt\n");
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值