时间相关的函数
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 *stdin | stdin->fileno | 0 |
FILE *stdout | stdout->fileno | 1 |
FILE *stderr | stderr->fileno | 2 |
文件描述符的总量
默认是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;
}