文件IO:
1.打开文件 open
2.读写文件 read write
3.关闭文件 close
1.打开文件:
open
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
open
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 文件存在清0
O_APPEND 追加
O_EXCL 文件存在报错
O_NONBLOCK 非阻塞
O_ASYNC 异步IO
..
mode:权限
只要有O_CREAT标识,表示需要加上权限:
rwx rwx rwx
rw- rw- r--
110 110 100
0 6 6 4
返回值:
成功返回文件描述符
失败返回-1
文件描述符:很小的非负整数,而且新的文件描述符总是尚未被使用的最小的非负整数
标准IO的文件描述符
0 STDIN_FILENO -> stdin
1 STDOUT_FILENO -> stdout
2 STDERR_FILENO -> stderr
2.关闭文件
close
int close(int fd);
close
int close(int fd);
功能:
关闭文件描述符
成功返回0
失败返回-1
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
int main()
{
int fd=0;
fd=open("file.txt",O_RDONLY|O_CREAT|O_EXCL,0664);//r
// fd=open("file.txt",O_RDWR|O_CREAT|O_EXCL,0664); //r+
// fd=open("file.txt",O_WRONLY|O_CREAT|O_TRUNC,0664);//w
//fd=open("file.txt",O_RDWR|O_CREAT|O_TRUNC,0664); //w+
//fd=open("file.txt",O_RDONLY|O_CREAT|O_APPEND,0664);//a
//fd=open("file.txt",O_RDWR|O_CREAT|O_APPEND,0664); //a+
if(-1==fd)
{
perror("failed");
return -1;
}
close(fd);
}
3.write
ssize_t write(int fd, const void *buf, size_t count);
3.write
ssize_t write(int fd, const void *buf, size_t count);
功能:
向文件描述符中写入buf开始的count个字节
参数:
fd:文件描述符
buf:写入的数据
count:写入的字节数
返回值:
成功返回写入的字节数
失败返回-1
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{
int fa=0;
char str[32]={"how are you"};
fa=open("file.txt",O_WRONLY|O_CREAT|O_TRUNC,0664);
if(fa==-1)
{
perror("failed");
return -1;
}
write(fa,"hello world",11);
write(fa,str,strlen(str));
close(fa);
return 0;
}
4.read
ssize_t read(int fd, void *buf, size_t count);
read
ssize_t read(int fd, void *buf, size_t count);
功能:
从文件描述符中读取数据到buf开始的空间中,最多读取count个字节
参数:
fd:文件描述符
buf:存放数据空间首地址
count:最多读取的字节数
返回值:
成功返回读取的字节数
读到文件末尾返回0
失败返回-1
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{
int fd=0;
char str[32]={0};
ssize_t nret=0;
fd=open("file.txt",O_RDONLY);
if(-1==fd)
{
perror("failed");
return -1;
}
nret=read(fd,str,sizeof(str));//从fd中读取数据到str中,最多读sizeof(str)个字节
printf("读到%ld个字节\n",nret);
printf("读到的内容为%s\n",str);
close(fd);
return 0;
}
5.lseek
off_t lseek(int fd, off_t offset, int whence);
5.lseek
off_t lseek(int fd, off_t offset, int whence);
功能:
修改文件描述符对应的偏移量
参数:
fd:文件描述符
offset:偏移量
whence:
SEEK_SET:从文件开头开始偏移
SEEK_CUR:从当前位置开始偏移
SEEK_END:从文件末尾开始偏移
返回值:
成功返回当前的偏移量
失败返回-1
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{
int fd=0;
off_t len=0;
fd=open("file.txt",O_WRONLY|O_CREAT|O_TRUNC,0664);
if(-1==fd)
{
perror("failed");
return -1;
}
char ch='a';
len=lseek(fd,10,SEEK_SET);
printf("len=%ld\n",len);
write(fd,&ch,1);
ch='b';
len=lseek(fd,-5,SEEK_END);
printf("len=%ld\n",len);
write(fd,&ch,1);
ch='c';
len=lseek(fd,2,SEEK_CUR);
printf("len=%ld\n",len);
write(fd,&ch,1);
close(fd);
return 0;
}
标准IO和文件的区别:
fopen -> open
fgetc/fputc -> read/write
fgets/fputs
fscanf/fprintf
fread/fwrite
fclose -> close
fseek -> lseek
rewind
ftell
1.标准IO是库函数
2.文件IO是系统调用
3.标准IO是针对于文件IO的封装
4.标准IO是有缓存的
5.文件IO是没有缓存的
6.标准IO主要用于操作普通文件
7.文件IO可以操作设备文件、进程间通信的文件、普通文件(Linux系统下的一切文件均可以使用文件IO)
库函数:是针对于系统调用的封装,可以在Windows或者Linux系统中使用
系统调用:是Linux内核中的函数接口,只能在Linux系统中使用
其余函数接口:
1.fileno
标准IO -> 文件IO
int fileno(FILE *stream);
功能:
获得文件流指针对应的文件描述符
2.fdopen
文件IO -> 标准IO
FILE *fdopen(int fd, const char *mode);
功能:
通过文件描述符获得文件流指针
3.feof
检测是否读到文件末尾
4.ferror
检测是否出错
5.clearerr
清除错误
Linux系统中时间的获取:
1.time
time_t time(time_t *tloc);
功能:
返回1970年1月1日到现在的秒数
参数:
tloc:存放秒数空间的首地址
返回值:
成功返回1970年1月1日到现在的秒数
失败返回-1
2.localtime
struct tm *localtime(const time_t *timep);
功能:
将秒数转换为本地时间
参数:
timep:存放秒数空间的首地址
返回值:
成功返回本地时间
失败返回NULL
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) */
int tm_year; /* 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) */
int tm_isdst; /* Daylight saving time */
};
3.mktime
time_t mktime(struct tm *tm);
功能:
根据日历时间转换为1970年1月1日到现在的秒数
#include<stdio.h>
#include<time.h>
#include<unistd.h>
int main()
{
time_t t=0;
struct tm *ptm=NULL;
// ptm=time(NULL);
while(1)
{
time(&t);
ptm=localtime(&t);
printf("%04d-%02d-%02d %02d:%02d:%02d\r",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,\
ptm->tm_hour,ptm->tm_min,ptm->tm_sec);//'\r'回到最左端,即只在一行打印
fflush(stdout);//强制刷新stdout,printf遇到\n会强制刷新,现在是、\r
sleep(1);//休眠一秒
}
return 0;
}
4.gettimeofday
int gettimeofday(struct timeval *tv, struct timezone *tz);
功能:
返回tz时区1970年1月1日到tv的秒数,精确到微秒
参数:
tv:
struct timeval
{
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
tz:一般设置为NULL
返回值:
成功返回0
失败返回-1
#include"../head.h"
/*查找输入目录路径下所有的文件,不包括隐藏文件,并显示查找耗费的时间*/
int Listdir(char *dirname)
{
char filepath[1024]={0};
DIR *dp=NULL;
struct dirent *pp=NULL;
dp=opendir(dirname);
if(dp==NULL)
{
return -1;
}
while(1)
{
pp=readdir(dp);//接收目录项
if(pp==NULL)
{
return -1;
}
if('.'==*pp->d_name)//跳过隐藏文件
{
continue;
}
sprintf(filepath,"%s/%s",dirname,pp->d_name);//dirname是路径,pp->d_name是文件名,将绝对路径存入filepath
printf("%s\n",filepath);
if(DT_DIR==pp->d_type)//如果文件是目录文件则递归查找里面的文件(标红是虚拟机的问题)
{
Listdir(filepath);//递归调用List(filepath)
}
}
closedir(dp);
return 0;
}
int main()
{
char dirname[600]={0};
struct timeval start;
struct timeval end;
long ts=0;
struct tm *ptm=NULL;
printf("请输入目录路径:\n");
scanf("%s",dirname);
gettimeofday(&start,NULL);//获得从1970.1.1到查找前的秒数,精确到微秒
Listdir(dirname);
gettimeofday(&end,NULL);//获得从1970.1.1到查找后的秒数,精确到微秒
ts = (end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec);
printf("耗时 %ld.%ld s\n", ts / 1000000, ts % 1000000);
return 0;
}