文件IOday02--------时间编程与文件IO
目录
一,时间编程
1,概念:
2,在程序开发费时,可以获取标准时间(以秒为单位)
将标准时间转换为字符串格式的时间的函数 char *ctime(time_t*timep)
将标准时间转换为本地时间函数:struct tm *localtime(const time_t *timep);
将本地时间转化为字符串格式的时间函数:char * asctime(struct tm *tm);
二、文件IO
1,概念
1》文件描述符 fd
2》当运行程序时,系统会自动打开三个标准文件
3》程序(静态)
4》进程(动态)
2,出错处理
1》全局错误码errno
3,文件IO操作文件的函数
1》打开文件
2》关闭文件
3》从文件读数据
4》向文件中写数据
5》设置文件位移量
补充
1,复制文件描述符
2,文件描述符的重定向
作业练习:
文件I/O – 作业
任务描述
实现思路
附:一图看懂文件IO与标准IO的区别
一,时间编程
1,概念:
世界标准时间以格林威治时间为起点分为24个时区,从格林威治向东时间早,向西时间晚
2,在程序开发费时,可以获取标准时间(以秒为单位)
#include <time.h>time_t time(time_t *tloc); //参数 -----保存秒数的变量地址//返回值 --- 成功:秒数, 失败:-1
返回值是time_t类型,参数是time_t*类型
秒数: 从1970-01-01 00:00:00 到 此时此刻的秒数
例如:
#include <stdio.h>#include <time.h>int main(int argc,char **argv){time_t tm;printf("%ld\n",time(&tm));printf("tm = %ld\n",tm);return 0;}
将标准时间转换为字符串格式的时间的函数 char *ctime(time_t*timep)
参数是一个地址,一个time_t类型的地址
char *ctime(const time_t *timep);//参数 ----- time()返回的秒数//返回值 ----成功:字符串格式的时间,失败:NULL例如: int main(int argc,char **argv){time_t tm;//获取标准数据time(&tm);//将标准时间转为字符串printf("%s",ctime(&tm));return 0;}
将标准时间转换为本地时间函数:struct tm *localtime(const time_t *timep);
可以根据结构体tm选择性的将内容输出;
struct tm *localtime(const time_t *timep);//参数 -------- time()返回的秒数//返回值---- 成功:结构体struct tm的指针 失败:NULL struct tm{int tm_sec; /* Seconds. [0-60] (1 leap second) */int tm_min; /* Minutes. [0-59] */int tm_hour; /* Hours. [0-23] */int tm_mday; /* Day. [1-31] */int tm_mon; /* Month. [0-11] */int tm_year; /* Year - 1900. */int tm_wday; /* Day of week. [0-6] */int tm_yday; /* Days in year.[0-365] */int tm_isdst; /* DST. [-1/0/1]*/};例如: #include <stdio.h>#include <stdlib.h>#include <time.h>#define perr(str) ({ perror(str); exit(1);})int main(int argc,char **argv){time_t tm;struct tm * tmp;//获取标准数据time(&tm);tmp = localtime(&tm);#if 0if(tmp == NULL){perror("localtime");exit(1);}#elseif(tmp == NULL)perror("localtime");#endifprintf("%4d-%02d-%02d\n",tmp->tm_year+1900,tmp->tm_mon+1,tmp->tm_mday);printf("%02d:%02d:%02d\n",tmp->tm_hour,tmp->tm_min,tmp->tm_sec);return 0;}
将本地时间转化为字符串格式的时间函数:char * asctime(struct tm *tm);
参数是结构体tm指针,先通过struct tm *localtime(const time_t *timep);函数获取的本地时间,再通过asctime函数将本地时间转化为字符串格式
char *asctime(const struct tm *tm);例如: int main(int argc,char **argv){time_t tm;struct tm * tmp;//获取标准数据time(&tm);tmp = localtime(&tm);#if 0if(tmp == NULL){perror("localtime");exit(1);}#elseif(tmp == NULL)perr("localtime");#endifprintf("%4d-%02d-%02d\n",tmp->tm_year+1900,tmp->tm_mon+1,tmp->tm_mday);printf("%02d:%02d:%02d\n",tmp->tm_hour,tmp->tm_min,tmp->tm_sec);printf("%s",asctime(tmp));return 0;}
二、文件IO
1,概念
1》文件描述符 fd
顺序分配的非负整数
内核用以标识一个特定进程正在访问的文件
其他资源(socket、pipe等)的访问标识
2》当运行程序时,系统会自动打开三个标准文件
文件指针 文件描述符
标准输入 stdin 0 (STDIN_FILENO)
标准输出 stdout 1 (STDOUT_FILENO)
标准出错 stderr 2 (STDERR_FILENO)
3》程序(静态)
存放在磁盘文件中的可执行代码
通过exec函数族调用运行
4》进程(动态)
程序的一次执行过程
进程的标识(pid,ppid,…)
2,出错处理
1》全局错误码errno
在linux中,用于标记函数调用失败的信息,定义一个全局的变量errno,把它也称为全局错误码
在linux系统中,给全局错误码定义了以下一些错误值:
在errno.h中定义,全局可见
错误值定义为“EXXX”形式,如EACCESS
/usr/include/asm-generic/errno-base.h // 1-34个错误值 #define EPERM 1 /* Operation not permitted */#define ENOENT 2 /* No such file or directory */#define ESRCH 3 /* No such process */#define EINTR 4 /* Interrupted system call */#define EIO 5 /* I/O error */#define ENXIO 6 /* No such device or address */#define E2BIG 7 /* Argument list too long */#define ENOEXEC 8 /* Exec format error */#define EBADF 9 /* Bad file number */#define ECHILD 10 /* No child processes */.......#define ERANGE 34 /* Math result not representable *//usr/include/asm-generic/errno.h // 35 -- 133个错误值#define EDEADLK 35 /* Resource deadlock would occur */#define ENAMETOOLONG 36 /* File name too long */#define ENOLCK 37 /* No record locks available */.... #define EHWPOISON 133 /* Memory page has hardware error */
当程序中调用某个函数失败时,系统会修改errno的值,将错误值赋给errno
这是在程序中,可以通过读取errno的值,获取对应的错误信息,有两种方法:
方法一:调用perror()函数
void perror(const char *s);
//参数 ---- 字符串,表示错误信息的提示,调用失败的函数名
当调用某个函数失败时,系统会修改errno,此时调用perror()时,它会读取errno的值,打印出对应的错误信息
例如:
int main(int argc,char **argv){FILE *fp;if((fp = fopen("1.txt","r"))== NULL){printf("errno = %d\n",errno);perror("fopen");exit(1);}return 0;}
方法二:调用strerror()函数
#include <string.h>
char *strerror(int errnum);
//参数 --- 错误值
//返回值 ----成功:错误值对应的错误信息,失败:NULL
例如:
int main(int argc,char **argv){#if 1FILE *fp;if((fp = fopen("1.txt","r"))== NULL){printf("errno = %d\n",errno);//perror("fopen");fprintf(stderr,"fopen:%s\n",strerror(errno));exit(1);}fprintf(stderr,"%s\n",strerror(200));#elseint i;for(i = 1; i <= 133;i++)fprintf(stderr,"%d --->%s\n",i,strerror(i));#endifreturn 0;}
3,文件IO操作文件的函数
1》打开文件
#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);
//参数1 ----- 要打开的文件
//参数2 ----- 打开的方式:
O_RDONLY:只读方式打开文件。
O_WRONLY:只写方式打开文件。
O_RDWR:读写方式打开文件。
(以上三个每次放入int flags参数中只能选其中一个放入,下面的可以任意组合)
O_CREAT:如果该文件不存在,就创建一个新的文件,并用第三的参数为其设置权限。
O_EXCL:如果使用O_CREAT时文件存在,则可返回错误消息。这一参数可测试文件是否存在。
O_NOCTTY:使用本参数时,如文件为终端,那么终端不可以作为调用open()系统调用的那个进程的控制终端。守护进程、后台进程、精灵进程。
O_TRUNC:如文件已经存在,并且以读写或只写成功打开,那么先全部删除文件中原有数据。
O_APPEND:以添加方式打开文件,在打开文件的同时,文件指针指向文件的末尾。
//参数3 ------ 文件权限,当参数2中有O_CREAT时,必须要通过参数3设置文件权限,权限 = 0666 & ~umask
//返回值 ---- 成功:最小且没有被使用的文件描述符,失败:-1
例如:
#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#define perr(str) ({perror(str); exit(1);})int main(int argc,char **argv){int fd;if(argc !=2){fprintf(stderr,"Usage: %s <filename>\n",argv[0]);exit(1);}//打开文件if((fd = open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,0666)) < 0)//if((fd = open(argv[1],O_WRONLY)) < 0)perr("open");printf("%s打开成功!\n",argv[1]);//关闭文件close(fd);return 0;}
2》关闭文件
#include <unistd.h>int close(int fd);
3》从文件读数据
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count); //以字节流方式读取数据
//参数1 ----- 文件描述符
//参数2 ----- 保存数据的空间地址
//参数3 ----- 空间的大小
//返回值 ----- 大于0,表示读到的字节数,等于0,表示读到文件末尾,-1,失败。
例如:
int main(int argc,char **argv){int fd;char buf[100];int ret;if(argc !=2){fprintf(stderr,"Usage: %s <filename>\n",argv[0]);exit(1);}if((fd = open(argv[1],O_RDONLY)) < 0)perr("open");while(1){memset(buf,0,sizeof(buf));if((ret= read(fd,buf,sizeof(buf))) < 0)perr("read");else if(!ret)break;elseprintf("%s",buf);}close(fd);return 0;}
4》向文件中写数据
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
//参数1 ----- 文件描述符
//参数2 ----- 数据空间地址
//参数3 ----- 要写的数据长度
//返回值 ---- 成功:实际写的数据长度,失败: -1
例如: 封装write函数
void mywrite(int fd,char *buf,int count){int ret=0;while(1){if((ret = write(fd,buf+ret,count)) < 0)perr("write");if(ret != count)count = count - ret;elsebreak;}}
5》设置文件位移量
#include <sys/types.h>#include <unistd.h>off_t lseek(int fd, off_t offset, int whence);//参数1 ----- 文件描述符//参数2 ----- 相对于参数3的偏移量//参数3 ----- 参数2的起始位置: SEEK_SET ----- 文件开头SEEK_CUR ----- 文件位移量的当前位置SEEK_END ----- 文件末尾//返回值 ---- 成功: 文件位移量,失败:-1创建空洞文件: ------- //创建空洞文件时,不能以追加方式打开文件步骤一: 修改文件位移量到指定的大小步骤二: 在修改后的文件位移量位置写一个标签。int main(int argc,char **argv){int fd;int n;if(argc !=2){fprintf(stderr,"Usage: %s <filename>\n",argv[0]);exit(1);}if((fd = open(argv[1],O_WRONLY|O_CREAT,0666)) < 0)perr("open");printf("请输入文件的大小:");scanf("%d",&n);//1,设置文件位移量lseek(fd,n-3,SEEK_SET);//2,写入一个标签write(fd,"end",3);close(fd);return 0;}
补充
1,复制文件描述符
int dup(int oldfd);
//参数 --- 要复制的文件描述符
//返回值 ---成功:最小没有被使用的文件描述符,该文件描述符是ledfd的一个拷贝
int main(int argc,char **argv){int fd,newfd;char buf[100];if(argc !=2){fprintf(stderr,"Usage: %s <filename>\n",argv[0]);exit(1);}if((fd = open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,0666)) < 0)perr("open");printf("请输入一个字符串:");fgets(buf,sizeof(buf)-1,stdin);write(fd,buf,strlen(buf));//复制文件描述符fd,返回新的文件描述符,该文件描述符是fd的一个拷贝newfd = dup(fd);printf("请输入一个字符串:");fgets(buf,sizeof(buf)-1,stdin);if(write(newfd,buf,strlen(buf)) < 0)perr("write");close(fd);return 0;}
2,文件描述符的重定向
int dup2(int oldfd, int newfd); //把newfd重定向到oldfd,在重定向之前,会关闭newfd对应的文件
//参数1 ---- 目标文件描述符
//参数2 ---- 需要重定向的文件描述符
//返回值 ----- 成功:返回重定向后的文件描述符,失败:-1
例如:
int main(int argc,char **argv){int fd,newfd;char buf[100];if((fd = open("1.txt",O_WRONLY|O_CREAT|O_TRUNC,0666)) < 0)perr("open");if((newfd = open("2.txt",O_WRONLY|O_CREAT|O_TRUNC,0666)) < 0)perr("open");#if 0//将标准输出重定向到文件中dup2(fd,STDOUT_FILENO);printf("hello world\n");#elsewrite(fd,"hello",5);dup2(fd,newfd); //把newfd重定向到fd,同时关闭newfd原来的文件write(newfd,"world",5);#endifclose(fd);close(newfd);return 0;}
作业练习:
文件I/O – 作业
任务描述
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
//封装write,防止有些内容写不全
void mywrite(int fd,char *buf,int count)
{int ret=0;while(1){if((ret=write(fd,buf+ret,count))<0)perror("write");if(ret!=count){count=count-ret;}elsebreak;}
}int main(int argc,char **argv)
{int wwq,qww;int ret,i=0;char buf[1000];
//判断传入文件数是否正常if(argc!=3){fprintf(stderr,"Usage: %s <filename>\n",strerror(errno));exit(1);}
//判断传入文件是否打开正常打开if((wwq=open(argv[1],O_RDONLY))<0){ fprintf(stderr,"Usage: %s <filename>\n",strerror(errno));exit(1);}if((qww=open(argv[2],O_WRONLY))<0){ fprintf(stderr,"Usage: %s <filename>\n",strerror(errno));exit(1);}while(1){//初始化buf空间,令其内容全部为0memset(buf,0,sizeof(buf));//读出是否正常,并把内容存入bufif(ret=read(wwq,buf,sizeof(buf))<0){perror("read");}//while循环退出的条件,当读至文件末端会返回0,使得ret=0;else if(!ret)break;//将buf内容写入qwwmywrite(qww,buf,strlen(buf));}fprintf(stdout,"内容为:%s\n",buf);close(wwq);close(qww);return 0;}
实现思路
提示:
附:一图看懂文件IO与标准IO的区别
文件IOday02--------时间编程与文件IO相关推荐
- mfc打开指定路径下指定类型文件_Windows 网络编程:文件操作
一次性进群,长期免费索取教程,没有付费教程. 教程列表见微信公众号底部菜单 进微信群回复公众号:微信群:QQ群:460500587 微信公众号:计算机与网络安全 ID:Computer-network ...
- android java 写文件操作_Android编程之文件的读写实例详解
本文实例分析了Android编程之文件的读写方法.分享给大家供大家参考,具体如下: Android的文件读写与JavaSE的文件读写相同,都是使用IO流.而且Android使用的正是JavaSE的IO ...
- php 修改文件访问时间,PHP获取文件创建日期、修改日期、访问时间
最近由于项目的需求需要对服务器上面的文件做一个时间的记录,接下来吾爱编程就为大家介绍一下PHP获取文件创建日期.修改日期.访问时间的方法,有需要的小伙伴可以参考一下: 1.常用代码: (1).file ...
- linux 禁止文件修改时间,linux 修改文件的时间属性
二.修改文件时间 创建文件我们可以通过touch来创建.同样,我们也可以使用touch来修改文件时间.touch的相关参数如下: -a : 仅修改access time. -c : 仅修改时间,而不建 ...
- php 修改文件访问时间,php获取文件的创建、修改时间及访问时间
filemtime() 函数返回文件内容上次的修改时间 若成功,则时间以 Unix 时间戳的方式返回.若失败,则返回 false. 语法 : filemtime(filename) 参数描述 file ...
- fatjar打包mysql_一个简单的解压ZIP Excl文件---gt;按时间读取Excle文件,通过Fat jar打成jar相对应的添加到mysql数据库中。 - 明月 - ITeye博客...
写道 一个简单的解压ZIP Excl文件--->按时间读取Excle文件,通过Fat jar打成jar相对应的添加到mysql数据库中. package common.gaoyang; impo ...
- Linux文件管理(基础):文件的时间、文件的扩展名、系统目录结构与作用、绝对路径与相对路径、文件管理、vi\vim
文章目录 一. Linux系统的单根目录结构 文件的时间 文件的扩展名 二. 系统目录结构与作用 三. 绝对路径与相对路径 四. 文件管理 4.1 文件管理之:基本命令 4.2 文件管理之:创建/复制 ...
- linux 查找目录或文件,linux 查找目录或文件详解
查找目录:find /(查找范围) -name '查找关键字' -type d 查找文件:find /(查找范围) -name 查找关键字 -print 如果需要更进一步的了解,可以参看Linux的命 ...
- Linux系统编程【文件IO、进程、进程间通信、信号、线程、互斥】
linux系统编程 个人通过学习,手打了一份48000字的Linux系统编程的笔记,包含了[文件IO.进程.进程间通信.信号.多线程.互斥]等知识点,并给出了大量的代码案例对每个重要的知识点进行了代码 ...
最新文章
- C++五子棋(三)——判断鼠标有效点击
- linux中挂载系统光盘,linux下挂载光盘
- OAuth2.0学习(1-1)OAuth2.0是什么?
- Vue 添加外部的时间插件不触发v-model事件更改数据
- Socket编程实践(6) --TCP服务端注意事项
- Java Protected 解读
- Spring按类型自动装配注入数组、集合、Map
- android 异步图片加载 开源,异步加载图片BitmapFun分析
- linux wget无法下载文件,wget下载文件
- 小猫爪:i.MX RT1050学习笔记24-eDMA之eDMASAIASRC的“纠缠”(RT1170)
- RNA 二级结构预测方法
- 第二届天府大地艺术季(春)三道堰青杠树村分会场开幕
- ANO Tech 匿名四轴 制作分享
- js生成html转换成图片保存,js将html生成为图片,并保存在本地
- A Co-Memory Network for Multimodal Sentiment Analysis
- 卫星影像免费下载地址
- CentOS7 安装php7.4
- 千里马常有,而伯乐不常有
- EAUML日拱一卒 用例图开篇
- 达尔文流媒体服务器搭配
热门文章
- NYOJ 买牛奶(水题)
- Tomcat7.0浅析
- 我的程序员之路:11 年高考结束到 17 年日本修士的心路历程
- 没有基础能学会UI设计吗 有没有学习路线推荐
- day55 django 模型层,orm连表操作
- iphone html阅读,iPhone如何使用Safari浏览器阅读列表功能
- react-native打包release版本闪退
- JS--数据类型--渡一教育(视频笔记)
- 科罗拉多矿业大学计算机科学专业,科罗拉多矿业大学专业设置情况_有哪些专业...
- 使用Git管理SVN