man手册
1.普通命令
2.系统调用的函数
3.库函数
4.特殊文件
5.文件格式
6.游戏
7.附加的一些变量
IO介绍
对文件的输入和输出 输入:写文件 将文件中的内容写到内存中去
输出: 读文件,讲内存中的内容读到文件中
linux下一切皆文件
文件类型(七种)
b:块设备文件
c:字符设备文件
d: 目录文件
-:普通文件
l:链接文件
s:嵌套字文件
p:管道文件
标准IO和文件IO
文件IO
内核向上提供输入输出函数接口,叫做系统调用函数接口。基于内核,内核不同,系统调用函数接口不同,文件IO不同操作系统函数接口不同。可移植性较差。
标准IO
标准IO是C库中定义的一组用于输入输出的函数接口。不同的操作只要移植了C库就可以使用,它是在系统调用之前做了个二次封装,相当于是间接进行了系统调用。可移植性强,可以在不同的系统环境下进行使用
标准IO的调用逻辑
标准IO读写
if(是linux操作系统)
{
调用的就是linux的内核函数接口(文件IO)
}
if(是windows操作系统)
{
调用的就是windows的内核函数接口(文件IO)
}
if(是macos操作系统)
{
调用的就macos的内核函数接口(文件IO)
}
标准IO在系统调用之前作了二次封装增加了缓存机制,减少了系统调用的次数,提高了程序的效率。
正常的系统调用:
应用层读写文件-》调用内核层的函数接口-》与硬件进行交互-》每次读写重复
带有缓存机制:
应用层读写文件-》调用内核层的函数接口-》与硬件进行交互-》拿到数据返回给应用层的缓存区-》每次读写从缓存区读取
标准IO 的特点
标准IO是c库中提供的一组专门用于输入输出的函数接口
标准IO由ANSI C标准定义,不仅能在Unix操作系统上,在很多的操作系统上都实现了标准IO
标准IO通过缓存机制,减少系统调用的次数,提高效率
标准IO围绕流进行操作(stream),在标准IO中,流用FILE*来描述
标准IO默认打开三个流:标准输入(stdio),标准输出(stdout),标准出错(stderr)
流
定义:
所有的I/O操作仅是简单的从程序移进或移出,这种字节流,称为流
分类:
文本流/二进制流
流指针FILE*
FILE*是一个指向FILE结构体的指针,这个结构体有标准库定义,用于表示一个打开的文件或输入/输出流
查看结构体:vi -t FILE
输入
追:ctrl+]
_IO_buf_base:缓存区的起始地址
_IO_buf_结束:缓存区的结束地址
缓存区的分类
1全缓存:基于文件
刷新全缓存:
1.程序正常退出
遇到return(main)
exit退出进程
关闭fclose流指针
2.fflush强制刷新缓存
3.缓存区满
2.行缓存–>基于终端:stdin\stdout
刷新缓存区:
1.程序正常退出
遇到return(main)
exit退出进程
关闭fclose流指针
2.fflush强制刷新缓存
3.缓存区满
4.\n刷新
3.不缓存:stderr
注意:缓存区只有在使用的时候才会开辟
实例
非正常结束不刷新
#include<stdio.h>
int main()
{
printf(“hello,world”);
while(1)
{}
return 0;
}
\n刷新
缓存区满
fflush:强制刷新
#include <stdio.h>
int fflush(FILE *stream);
功能:刷新缓存区
参数:
stream:流 (NULL:刷新所有流)
返回值:成功0
失败EOF(-1),更新errno。
用法:fflush(NULL);
标准IO 的函数接口
1. 打开文件:fopen
2. 关闭文件:fclose
3.读/写单个字符:fgetc fputc
4. 读/写一串字符串:fgets fputs
5. 读/写一个二进制文件:fread fwrite
6. 移动指针:fseek
fopen(打开文件)
#include <stdio.h>
FILE *fopen(const char *path, const char *mode);
功能:打开文件
fopen()函数打开由 pathname 指向的文件名对应的文件,并为该文件关联一个流。
参数“argument mode”指向一个以以下序列开头的字符串(可能还包含下面描述的其他字符):
参数:path:打开的文件的路径
mode:打开方式
打开方式:
r:只读,文件指针定位到文件开头(有文件)
r+:可读可写,文件指针定位到文件开头(有文件)
w:只写,文件不存在创建,存在清空,文件指针定位到文件开头
w+:可读可写,文件不存在创建,存在清空,文件指针定位到文件开头
a: 只写,文件不存在创建,存在追加(到文件末尾)
a+:可读可写,文件不存在创建,存在追加(到文件末尾)
读文件指针定位到文件开头。
返回值:成功-的到文件流指针
失败:NULL,更新errno
实例代码:
一个任务中最多可以打开1024个文件,且一个文件可以被重复打开
注意:打开的文件属于有限资源,最多打开1024个,文件可以被重复打开,打开的文件不用了需要及时关闭
fclose(关闭文件)
int fclose(FILE *stream);
功能:关闭文件
参数:
stream:流指针
返回值:成功0,失败-1,更新errno
示例代码
#include <stdio.h>
int main(int argc, char const *argv[])
{
//打开一个名字叫test.c的文件,以只读的形式
FILE *fp = fopen("./test.c","r");
if (fp == NULL)
{
perror("fopen filed");
return -1;
}
printf("open success\n");
if(close(fp)==-1)
{
printf("close success\n")
};
return 0;
}
perror
#include <errno.h>
void perror(const char *s);
功能:根据errno值获取错误信息,将信息输出到终端
参数:S:提示内容
返回值:无
fgetc(读取单个字符)
int fgetc(FILE *stream);
功能:从文件中读一个字符
参数:
stream:流指针(从那个文件读)
返回值:成功返回读到字符的ascii值,失败返回或读到文件结尾返回-1.
fputc(写单个字符)
int fputc(int c, FILE *stream);
功能:向指定的文件中写入一个字符
参数:
c:要写入字符的ASCII值
stream:流指针
返回值:写入字符ASCII值
失败返回:EOF
练习:用fgetc和fputc实现cp功能,将A文件中的内容放入B文件
#include <stdio.h>
int main(int argc, char const *argv[])
{
// 打开文件
FILE *fp_src = fopen("./fopen.c", "r");
if (fp_src == NULL)
{
perror("open src filed");
return -1;
}
FILE *fp_dest = fopen("./test.c", "w");
if (fp_dest == NULL)
{
perror("open dest filed");
return -1;
}
//循环读取文件
char ch;
while ((ch = fgetc(fp_src)) != -1)
{
fputc(ch,fp_dest);
}
printf("读取完成\n");
fclose(fp_src);
fclose(fp_dest);
return 0;
}
fprintf(向指定文件写入数据)
#include<stdio.h>
int fprintf(FILE *stream, const char *format, ...);
功能:向指定的文件以指定的格式写入数据
参数: stream :流指针
format:指定格式
...:多个参数
返回值:输出字符个数
失败返回:EOF
示例代码:
#include <stdio.h>
int main(int argc, char const *argv[])
{
// 打开一个名字叫test.c的文件,以只读的形式
FILE *fp = fopen("./a.txt", "w+");
if (fp == NULL)
{
perror("fopen filed");
return -1;
}
printf("open success\n");
int age = 21;
const char *name = "jj";
double height = 156.666;
fprintf(stdout,"age:%d\n",age);
fprintf(fp,"name:%s\n",name);
fprintf(fp,"height:%lf\n",height);
fclose(fp);
return 0;
}
fgets(获取字符串)
char *fgets(char *s, int size, FILE *stream);
功能:从文件中获取指定长度的字符串
参数: s:字符串存放的首地址
size:期望获取字符的个数
实际读size-1个字符,会自动补'\0',预留一个位置补'\0'.
文件中不满size-1个,有多少读多少,都会补'\0'.
当读到'\n',结束,不再读下一行内容,再次调用fgets继续从下一行开始读。
stream:文件流指针
返回值:
成功:返回获取成功字符串存放的首地址
失败或读到文件结尾返回NULL。
示例代码:
#include <stdio.h>
int main(int argc, char const *argv[])
{
// 打开一个名字叫test.c的文件,以只读的形式
FILE *fp = fopen("./a.txt", "r");
if (fp == NULL)
{
perror("fopen filed");
return -1;
}
printf("open success\n");
char buf[64];
while (fgets(buf, sizeof(buf), fp) != NULL)
{
printf("buf:%s", buf);
}
fclose(fp);
return 0;
}
文件指针偏移函数
1. rewind
void rewind(FILE *stream)
功能:将文件指针定位到文件开头
参数:流指针
2.ftell
long ftell(FILE *stream)
功能:计算文件指针当前的位置(相对于文件开头)
返回值:成功:返回当前文件指针相较于开头的字节数
失败:-1;
3.fseek
int fseek(FILE *stream, long offset, int whence);
功能:将文件指针偏移到指定位置
参数:
stream:流指针
offset:偏移量 +5 --》相对于位置向后偏移5byte
-5 --》相对于位置向前偏移5byte
whence:相对位置
SEEK_SET:开头
SEEK_CUR:当前
SEEK_END:结尾
返回值:成功:0
失败:-1,更新errno
举例:
fseek(fp,-10,SEEK_END)
fseek(fp,-10,SEEK_CUR)
练习:使用ftell计算文件的长度
#include <stdio.h>
int main(int argc, char const *argv[])
{
FILE *fp = fopen(argv[1],"r");
if (fp == NULL)
{
perror("fopen filed");
return -1;
}
//定位到文件的末尾
fseek(fp,0,SEEK_END);
//计算文件的长度
long lenth = ftell(fp);
printf("len:%ld",lenth);
fclose(fp);
return 0;
}