目录
一、标准I/O
1.1.fseek
1.偏移量
2.实例
编辑
1.2.ftell
2.实例
编辑
二、文件I/O
2.1.打开文件
1.open
2.2.实例
2.2.读写文件
1.write
实例
编辑
2.read
实例
2.3.关闭文件
1.close
2.3.lseek
实例
三、标准I/O与文件I/O的区别
3.1.区别
四、其余函数接口
4.1.fileno
4.2.fdopen
4.3.feof
4.4.ferror
4.5.clearerr
五、Linux中时间的获取
5.1.time
5.2.localtime
默认的结构体
5.3.mktime
5.4.实例
1.获取实时时间
2.将日历时间转化位1907年1月1日到2024年8月1日19:32的秒数
五、总结
一、标准I/O
1.1.fseek
1.偏移量
读和写都是在偏移量的位置上进行的
int fseek(FILE *stream, long offset, int whence);
功能:
设置流的偏移量
参数:
stream:文件流指针
offset:偏移量
whence:
SEEK_SET 文件开头
SEEK_CUR 当前位置
SEEK_END 文件结尾
返回值:
成功返回当前偏移量
失败返回-1
2.实例
#include <stdio.h>
int main(void)
{
FILE *fp = NULL;
fp = fopen("a.txt", "w");
if(fp == NULL)
{
return -1;
}
fseek(fp, 5, SEEK_SET);
fputc('a', fp);
fseek(fp, -2, SEEK_END);
fputc('B', fp);
fseek(fp, 5, SEEK_CUR);
fputc('c', fp);
fclose(fp);
return 0;
}
1.2.ftell
获取流的偏移量(文件大小)
2.实例
#include <stdio.h>
int main(void)
{
FILE *fp = NULL;
long len = 0;
fp = fopen("/usr/include/stdio.h", "r");
if (NULL == fp)
{
perror("fail to fopen");
return -1;
}
fseek(fp, 0, SEEK_END);
len = ftell(fp);
printf("len = %ld\n", len);
fclose(fp);
return 0;
}
二、文件I/O
2.1.打开文件
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 文件存在清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
文件描述符:很小的非负整数,而且新的文件描述符总是尚未被使用的最小的非负整数
2.2.实例
与"r"等价
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
int fd = 0;
fd = open("a.txt", O_RDONLY);
if(fd == -1)
{
perror("open failed");
return -1;
}
return 0;
}
与r+等价
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
int fd = 0;
fd = open("a.txt", O_RDWR);
if(fd == -1)
{
perror("open failed");
return -1;
}
return 0;
}
与w等价
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
int fd = 0;
fd = open("a.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);
if(fd == -1)
{
perror("open failed");
return -1;
}
return 0;
}
与w+等价
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
int fd = 0;
fd = open("a.txt", O_RDWR | O_CREAT | O_TRUNC, 0664);
if(fd == -1)
{
perror("open failed");
return -1;
}
return 0;
}
与a等价
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
int fd = 0;
fd = open("a.txt", O_WRONLY | O_CREAT | O_APPEND, 0664);
if(fd == -1)
{
perror("open failed");
return -1;
}
return 0;
}
与a+等价
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
int fd = 0;
fd = open("a.txt", O_RDWR | O_CREAT | O_APPEND, 0664);
if(fd == -1)
{
perror("open failed");
return -1;
}
return 0;
}
2.2.读写文件
1.write
ssize_t write(int fd, const void *buf, size_t count);
功能:
向文件描述符中写入buf开始的count个字节
参数:
fd:文件描述符
buf:写入的数据
count:写入的字节数
返回值:
成功返回写入的字节数
失败返回-1
实例
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
int fd = 0;
char strbuffer[256] = {"how are you"};
fd = open("a.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);
if(fd == 0)
{
perror("open failed");
return -1;
}
write(fd, "hello world", 11);
write(fd, strbuffer, strlen(strbuffer));
close(fd);
return 0;
}
2.read
ssize_t read(int fd, void *buf, size_t count);
功能:
从文件描述符中读取数据到buf开始的空间中,最多读取count个字节
参数:
fd:文件描述符
buf:存放数据空间首地址
count:最多读取的字节数
返回值:
成功返回读取的字节数
读到文件末尾返回0
失败返回-1
实例
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int fd = 0;
char strbuffer[128] = {0};
ssize_t ret = 0;
fd = open("a.txt", O_RDONLY);
if(fd == 0)
{
perror("");
return -1;
}
ret = read(fd, strbuffer, sizeof(strbuffer));
printf("读到了%ld个字节\n", ret);
printf("内容为:%s\n", strbuffer);
close(fd);
return 0;
}
2.3.关闭文件
1.close
需要加入
#include <unistd.h>
关闭文件符
int close(int fd);
功能:
关闭文件描述符
成功返回0
失败返回-1
2.3.lseek
off_t lseek(int fd, off_t offset, int whence);
功能:
修改文件描述符对应的偏移量
参数:
fd:文件描述符
offset:偏移量
whence:
SEEK_SET:从文件开头开始偏移
SEEK_CUR:从当前位置开始偏移
SEEK_END:从文件末尾开始偏移
返回值:
成功返回当前的偏移量
失败返回-1
实例
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int fd = 0;
char c = 0;
off_t len = 0;
fd = open("a.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);
if(fd == 0)
{
perror("");
return -1;
}
len = lseek(fd, 10, SEEK_SET);
c = 'a';
write(fd, &c, 1);
printf("len = %ld\n", len);
len = lseek(fd, -5, SEEK_CUR);
c = 'b';
write(fd, &c, 1);
printf("len = %ld\n", len);
lseek(fd, 0, SEEK_SET);
c = 'c';
write(fd, &c, 1);
printf("len = %ld\n", len);
close(fd);
return 0;
}
三、标准I/O与文件I/O的区别
fopen -> open
fgetc/fputc -> read/write
fgets/fputs
fscanf/fprintf
fread/fwrite
fclose -> close
fseek -> lseek
rewind
ftell
3.1.区别
1.标准IO是库函数
2.文件IO是系统调用
3.标准IO是针对于文件IO的封装
4.标准IO是有缓存的
5.文件IO是没有缓存的
6.标准IO主要用于操作普通文件
7.文件IO可以操作设备文件、进程间通信的文件、普通文件(Linux系统下的一切文件均可以使用文件IO)
库函数:是针对于系统调用的封装,可以在Windows或者Linux系统中使用
系统调用:是Linux内核中的函数接口,只能在Linux系统中使用
四、其余函数接口
4.1.fileno
标准IO -> 文件IO
int fileno(FILE *stream);
功能:
获得文件流指针对应的文件描述符
4.2.fdopen
文件IO -> 标准IO
FILE *fdopen(int fd, const char *mode);
功能:
通过文件描述符获得文件流指针
4.3.feof
检测是否读到文件末尾
4.4.ferror
检测是否出错
4.5.clearerr
清楚错误
五、Linux中时间的获取
5.1.time
time_t time(time_t *tloc);
功能:
返回1970年1月1日到现在的秒数
参数:
tloc:存放秒数空间的首地址
返回值:
成功返回1970年1月1日到现在的秒数
失败返回-1
5.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 */
};
5.3.mktime
可以用来求时间段的差时
time_t mktime(struct tm *tm);
功能:
根据日历时间转换为1970年1月1日到现在的秒数
5.4.实例
1.获取实时时间
#include <stdio.h>
#include <time.h>
#include <unistd.h>
int main(void)
{
time_t t;
struct tm *ptime = NULL;
while(1)
{
time(&t);
ptime = localtime(&t);
printf("%04d-%02d-%02d %02d:%02d:%02d\r", ptime->tm_year+1900, ptime->tm_mon+1, ptime->tm_mday, ptime->tm_hour, ptime->tm_min, ptime->tm_sec);
fflush(stdout);
sleep(1);
}
return 0;
}
2.将日历时间转化位1907年1月1日到2024年8月1日19:32的秒数
#include <stdio.h>
#include <time.h>
#include <unistd.h>
int main(void)
{
time_t t;
struct tm *ptm = NULL;
struct tm tmp;
tmp.tm_hour = 19;
tmp.tm_min = 32;
tmp.tm_sec = 0;
tmp.tm_year = 2024-1900;
tmp.tm_mon = 8-1;
tmp.tm_mday = 1;
t = mktime(&tmp);
printf("t = %ld\n", t);
t = time(NULL);
printf("t = %ld\n", t);
return 0;
}
五、总结
2024年8月1日,今天时学习的19天,时间飞逝。今天将标准IO的函数接口学完了,并且学了一大半的文件IO的接口。今天最有意思的加上学了Linux上如何求实时时间,很有意思很有收获。
加油!