前面讲了statfs函数和opendir函数,但是要获取某个文件的大小和创建时间呢?statfs函数和opendir函数不能办到。
我们想到了ls -l 命令,那么对应的linux函数是什么?就是stat函数了。
表头文件: #include <sys/stat.h>
函数定义: int stat(const char *file_name, struct stat *buf);
函数说明: 通过文件名filename获取文件信息,并保存在buf所指的结构体stat中
返回值: 执行成功则返回0,失败返回-1,错误代码存于errno(需要include <errno.h>)
stat结构体定义:
struct stat {
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; //文件字节数(文件大小)
unsigned long st_blksize; //块大小(文件系统的I/O 缓冲区大小)
unsigned long st_blocks; //块数
time_t st_atime; //最后一次访问时间
time_t st_mtime; //最后一次修改时间
time_t st_ctime; //最后一次改变时间(指属性)
};
那么现在可以上代码了:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
int main()
{
char *filename="/media/test/opendir.c";
struct stat info;
struct tm *tmtest = NULL;
char timestrcur[40];
memset(&info, 0, sizeof(struct stat));
stat(filename, &info);
printf("size: %ld\n\n", (long int)info.st_size);//文件大小
printf("time_t:%lu\n",info.st_mtime);//打印time_t格式时间,单位是s,从1970年算起
printf("ctime: %s",ctime(&info.st_mtime));//打印ctime,将时间转换成字符串
tmtest = localtime(&info.st_mtime);
printf("asctime: %s", asctime(tmtest));//打印asctime格式时间
strftime(timestrcur,sizeof(timestrcur),"%Y-%m-%d %H-%M-%S",tmtest);
printf("time: %s\n", timestrcur);//打印要求格式的时间
return 0;
}
打印结果:
size: 1907
time_t:1411973541
ctime: Mon Sep 29 14:52:21 2014
asctime: Mon Sep 29 14:52:21 2014
time: 2014-09-29 14-52-21
关于时间处理部分有必要说明一下。
首先是stat函数得到的时间,是time_t类型,time_t实际上是长整型,到未来的某一天,从一个时间点(一般是1970年1月1日0时0分0秒)到那时的秒数(即日历时间),它所表示的时间不能晚于2038年1月18日19时14分07秒。
此外,time.h还提供了两种不同的函数将日历时间(一个用time_t表示的整数)转换为我们平时看到的把年月日时分秒分开显示的时间格式tm:
struct tm * gmtime(const time_t *timer);
struct tm * localtime(const time_t * timer);
只关注localtime这个函数
struct tm{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
再来说说
strftime()函数。
我们可以使用strftime()函数将时间格式化为我们想要的格式。它的原型如下:
size_t strftime(
char *strDest,
size_t maxsize,
const char *format,
const struct tm *timeptr
);
我们可以根据format指向字符串中格式命令把timeptr中保存的时间信息放在strDest指向的字符串中,最多向strDest中存放maxsize个字符。该函数返回向strDest指向的字符串中放置的字符数。
函数strftime()的操作有些类似于sprintf():识别以百分号(%)开始的格式命令集合,格式化输出结果放在一个字符串中。格式化命令说明串 strDest中各种日期和时间信息的确切表示方法。格式串中的其他字符原样放进串中。格式命令列在下面,它们是区分大小写的。
%a 星期几的简写
%A 星期几的全称
%b 月分的简写
%B 月份的全称
%c 标准的日期的时间串
%C 年份的后两位数字
%d 十进制表示的每月的第几天
%D 月/天/年
%e 在两字符域中,十进制表示的每月的第几天
%F 年-月-日
%g 年份的后两位数字,使用基于周的年
%G 年分,使用基于周的年
%h 简写的月份名
%H 24小时制的小时
%I 12小时制的小时
%j 十进制表示的每年的第几天
%m 十进制表示的月份
%M 十时制表示的分钟数
%n 新行符
%p 本地的AM或PM的等价显示
%r 12小时的时间
%R 显示小时和分钟:hh:mm
%S 十进制的秒数
%t 水平制表符
%T 显示时分秒:hh:mm:ss
%u 每周的第几天,星期一为第一天 (值从0到6,星期一为0)
%U 第年的第几周,把星期日做为第一天(值从0到53)
%V 每年的第几周,使用基于周的年
%w 十进制表示的星期几(值从0到6,星期天为0)
%W 每年的第几周,把星期一做为第一天(值从0到53)
%x 标准的日期串
%X 标准的时间串
%y 不带世纪的十进制年份(值从0到99)
%Y 带世纪部分的十制年份
%z,%Z 时区名称,如果不能得到时区名称则返回空字符。
%% 百分号
另外就是
ctime和asctime了
ctime:功能是 把日期和时间转换为字符串,而ctime类的对象表示的时间是基于格林威治标准时间(GMT)的。
用 法: char *ctime(const time_t *time);
asctime:是把时间换成ascii码
用 法: char *asctime(const struct tm *tblock);
关于时间的函数太多了,整理不完了,例如还有time﹑localtime﹑mktime﹑asctime﹑ctime﹑difftime﹑alarm和setitimer
,可参考:http://blog.chinaunix.net/uid-20564848-id-73411.html