Linux系统编程中的文件操作和时间读取

基于缓冲区的文件操作:

        属于高级的IO操作,其中以printf函数是基于缓冲区的文件操作,基于缓冲区的文件操作通常使用标准库中的<stdio.h>头文件提供的函数。这些函数大多数以f开头,表示它们是“文件”(file)相关的操作。

缓冲区的输出条件:

        程序正常结束;printf遇到\n也可以全部输出;缓冲区存满1024字节后将输出1024字节内容;遇到 fflush(stdout);

1.基于非缓冲区文件操作

属于低级IO操作,其中有打开文件函数open、读写write、read函数、close、控制光标位置lseek函数等。

1.打开文件(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);

参数:

        pathname:文件的路径/文件名

        flags:以下的三个宏定义,必须选择其一

              O_RDONLY或O_WRONLY或O_RDWR

                以下的宏定义自由选择:

                O_CREAT  //如果文件不存在就创建文件, 存在, 不起作用

                O_TRUNC  //清空

                O_APPEND  //追加

                O_EXCL:要求和O_CREAT连用,文件如果不存在,创建并打开,如果文件存在open直接返回失败(-1)

        mode:由flags决定,如果flags里面有O_CREAT,此时需要提供mode,否则,不用提供;mode文件的权限:八进制数,最终的文件权限:你提供的mode &(~umask)

返回值:成功int类型的文件描述符,失败返回-1;

       例:打开 1.txt,读写的方式打开,文件不存在创建,文件存在清空写

open(“1.txt”,O_RDWR|O_CREAT|O_TRUNC,0666);// 文件的权限被设置为 0666,这意味着文件所有者、组和其他用户都有读写权限(但注意,实际权限可能会受到umask的影响)

2.关闭文件(close

#include <unistd.h>

int close(int fd);

形参: open的返回值

返回值:returns zero on success. On error, -1 is returned

3.写操作(write

#include <unistd.h>

ssize_t write(int fd, const void*buf, size_t count);

参数

        fd:open的返回值

        buf:要写入的内容的首地址void *

        count:写入的字节数

返回值:成功返回真正写入的字节数,失败返回-1

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
//获取用户输入的账号和密码,并将它们写入到一个名为 "mima.txt" 的文件中。
int main()
{
	char username[32]={0};
	char passward[8]={0};
	printf("请输入账号:\n");
	scanf("%s",username);
	getchar();
	printf("请输入密码:\n");
	scanf("%s",passward);
	getchar();
	int fb = open("mima.txt",O_WRONLY);
    if (fb == -1) {  
        perror("打开文件失败open");  
        return 1;  
    }
	write(fb,username,sizeof(username));
	write(fb,"\n",1);
	write(fb,passward,sizeof(passward));
	close(fb);
	return 0;
}

4.读操作(read

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);

参数

        fd:open的返回值

        buf:读取到的内容存放的位置,提供空间即可

        count:要读取的字节数

返回值:成功返回真正读取到的字节数,失败返回-1;

5.光标偏移(lseek

#include <sys/types.h>

#include <unistd.h>

off_t lseek(int fd, off_t offset,int whence);

参数

        fd:open的返回值

        offset:偏移量

                +n 往文件末尾方向偏移n字节

                -n 往文件开头方向偏移n字节

        whence:偏移时的参考位置

                SEEK_SET  //文件开头

                SEEK_CUR  //文件当前位置

                SEEK_END  //文件末尾

返回值: 执行操作之后, 光标位置距离文件开头的偏移量

可以用此函数求文件大小:off_t size = fseek(fd,0,SEEK_END);

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
//读取文件中的的账号密码
int main()
{
	int fb = open("mima.txt",O_RDONLY);
	char name[32]={0};
	char ward[8]={0};
loop:
	printf("请输入账号:\n");
	scanf("%s",name);
	getchar();
	lseek(fb,0,SEEK_SET);
	int a=sizeof(name);
	char *p=malloc(a);
	read(fb,p,a);
	if(strcmp(p,name)==0)
	{
		read(fb,p,1);
		printf("请输入密码:\n");
		scanf("%s",ward);
		getchar();
		a=sizeof(ward);
		read(fb,p,a);
		if(strcmp(p,ward)==0)
		{
			printf("账号和密码输入正确\n");
			close(fb);
			return 0;
		}
		else
		{
			printf("密码输入错误\n");
			close(fb);
			return -1;
		}
	}
	else
	{
		printf("账号输入错误\n");
		goto loop;
		close(fb);
		
		return -1;
	}
	
	return 0;
}

可以利用读写操作实现文档的复制功能:从命令行参数指定的第一个文件中读取内容,然后将这些内容写入到第二个文件中,并最后从第二个文件中读取并打印内容。

(案例仅供参考,在打开文件时,我没有检查open函数是否成功返回了文件描述符。如果文件不存在或无法打开,则open会返回-1,但我没有处理这种情况,还有read和write函数也可能失败,也没有检查它们的返回值。在写代码时注意检查函数的返回值,来判断函数是否执行成功

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
    //检查命令行参数的数量如果参数数量不是3(包括程序名和两个文件名)则打印错误消息并结束程序
    if(argc != 3)
    {
        printf("参数错误!\n");
    }
    for (int i = 0; i < argc; i++)
    {
        printf("argv[%d]=%s\n",i,argv[i]);
    }
    //使用open函数以只读模式打开第一个文件,并将返回的文件描述符存储在fd中
   int fd = open(argv[1],O_RDONLY);
   //将文件位置指针移动到文件的末尾,然后获取文件的大小
   off_t size = lseek(fd,0,SEEK_END);
   if (size==0)
   {
    	close(fd);
		printf("%s无内容\n",argv[1]);
		return -1;
   }
    //将文件位置指针重置回文件的开头
   lseek(fd,0,SEEK_SET);
    //动态分配内存以存储整个文件的内容,分配的大小等于文件的大小
    char *p=malloc(size);
    read(fd,p,size);
    printf("p:%s",p);
    //以读写模式打开或创建第二个文件,并设置其权限为0666返回的文件描述符存储在fd1中
    int fd1=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0666);
    write(fd1,p,size);
    close(fd);
    close(fd1);
    //以只读模式重新打开第二个文件,并将返回的文件描述符存储在fd2中
    int fd2 = open(argv[2],O_RDONLY);
    lseek(fd2,0,SEEK_SET);
    ssize_t res=read(fd2,p,size);
    printf("res=%ld\n",res);
	printf("%s:%s",argv[2],p);
	close(fd2);
    return 0;
}

2.时间编程

1.和时间相关的指令

终端指令:data

终端输入: Cal

2.和时间编程相关的API函数

1)获取日历时间 -- 时间的秒数(time)

日历时间:1970年1月1日0点0分0秒举例现在的秒数

#include <time.h>

time_t time(time_t *tloc);

使用方法:

方式1:timt_t t = time(NULL);//time的返回值就是日历时间;

方式2:time_t t = 0;

             time(&t); //t里面就存放当前的日历时间

2)获取本地时间(localtime)

#include <time.h>

struct tm *localtime(const time_t *timep);

参数

       timep:日历时间,传日历时间地址

返回值: struct tm {

int tm_sec; /* 秒 */

int tm_min; /* 分 */

int tm_hour; /* 时 */

int tm_mday; /* Day of the month (1-31) */

int tm_mon; /* Month (0-11)+1 */

int tm_year; /* Year - 1900 +1900 */

int tm_wday; /* Day of the week (0-6, Sunday = 0) */

int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */

int tm_isdst; /* Daylight saving time */};

#include <stdio.h>
#include <time.h>
#include <unistd.h>
//打印本地时间60次(一分钟)
void Get_Time(void)
{
    time_t sj = time(NULL);
    struct tm *psj=localtime(&sj);
    printf("%d-%02d-%02d  %02d:%02d:%02d\n",psj->tm_year+1900,psj->tm_mon+1,psj->tm_mday,psj->tm_hour,psj->tm_min,psj->tm_sec);
}

int main()
{
    int num=60;
    while (num--)
    {
        Get_Time();
        sleep(1);
    }
    return 0;
}

3)获取格林威治 gmtime

struct tm *gmtime(const time_t *timep);

形参和返回值和localtime一样,结果中的时间形式是美国时间

4)获取时间的字符串(ctime)

char *ctime(const time_t *timep);

形参:timep日历时间,传地址

返回值:关于时间的字符串

5)获取时间的字符串 - asctime

char *asctime(const struct tm *tm);

形参:localtime或者gmtime的返回值

返回值:关于时间的字符串

       如果传参传的是localtime的返回值,关于时间的字符串是准确的

       如果传参传的是gmtime的返回值,关于时间的字符串差8hour

3.关于时间的字符串

功能:我们可以根据format指向字符串中格式命令把timeptr中保存的时间信息放在strDest指向的字符串中,最多向strDest中存放maxsize个字符。该函数返回向strDest指向的字符串中放置的字符数。

函数strftime()的操作有些类似于sprintf():识别以百分号(%)开始的格式命令集合,格式化输出结果放在一个字符串中。格式化命令说明串strDest中各种日期和时间信息的确切表示方法。格式串中的其他字符原样放进串中。格式命令列在下面,它们是区分大小写的。

size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);

参数

       s:存放格式化时间字符串

        max:时间字符串最大长度

        format:自定义格式,按照此格式,放在第一个参数给的字符串中

        tm:时间描述的结构体(gmtime / localtime返回值)

               如果是gmtime得到的结构体指针,时间差8小时

               如果是localtime得到的结构体指针,时间准确

%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 十进制的秒数

char buf[128] = {0}

例:strftime(buf,sizeof(buf),”%D %S %R”,loctm);

  • 33
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值