磁盘上的文件是文件。但是在程序设计中,一般认为文件有两种:程序文件、数据文件。
程序文件:包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。
数据文件:文件的内容不一定是程序,而是程序运行时读写的数据,如程序运行需要从中读取数据的文件,或者输出内容的文件。
本文讨论的是数据文件。
一个文件要有一个唯一的文件标识,以便用户识别和引用。
文件名包含3部分:文件路径+文件名主干+文件后缀。
例如: c:\code\test.txt
这里c:\code\为文件路径,test为文件主干,txt为文件后缀。
为了方便起见,文件标识常被称为文件名。
根据数据的组织形式,数据文件被分为文本文件或者二进制文件。
数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
一个数据在内存中是怎么存储的呢?
字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),存储的内容依次为’1’, ‘0’, ‘0’, ‘0’, ‘0’(注意这里是字符0,而不是数字0)
而二进制形式输出,则在磁盘上只占4个字节(VS2013测试)。
运行下面的代码,用二进制编译器打开in.txt。
(其中的文件操作函数会在下文具体讲到)
代码如下(示例):
int main()
{
int a = 10000;
FILE* pf = fopen("in.txt", "wb");
fwrite(&a, 4, 1, pf);
fclose(pf);
pf = NULL;
return 0;
}
此处16进制的00 00 27 10,即为10进制下的10000。
缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等,本质是一个结构体)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE。
例如,VS2013编译环境提供的 stdio.h 头文件中有以下的文件类型申明:
每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息。
一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。
文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。
ANSIC 规定使用fopen函数来打开文件,fclose来关闭文件。
//文件名 打开方式
FILE * fopen ( const char * filename, const char * mode );
//文件指针
int fclose ( FILE * stream );
文件的打开方式有很多种,这里介绍常用的几种
(1)“r”:只读,即打开文件并从文件中读内容,如果指定的文件不存在会报错。
(2)“w”:只写,即打开文件并向文件中输入内容,如果指定的文件不存在会自动创建一个新的文件。
(3)“a”:追加,即打开文件并向文件末尾添加内容,如果指定的文件不存在会报错。
(4)“rb”:只读,即打开二进制文件并从文件中读内容,如果指定的文件不存在会报错。
(5)“wb”:只写,即打开二进制文件并向文件中输入内容,如果指定的文件不存在会自动创建一个新的文件。
fputc原型:
int fputc(int c, FILE *stream);
运行下面的程序:
代码如下(示例):
int main()
{
FILE* pf = fopen("in.txt", "w");
fputc('a', pf);
fputc('b', pf);
fputc('c', pf);
fclose(pf);
return 0;
}
可以看到"in.txt"中已经依次写入了’a’,‘b’,'c’三个字符
代码如下(示例):
这时再用fgetc函数可依次得到文件中的字符。
fgetc原型
int fgetc(FILE *stream);
代码如下(示例):
int main()
{
FILE* pf = fopen("in.txt", "r");
printf("%c\n", fgetc(pf));
printf("%c\n", fgetc(pf));
printf("%c\n", fgetc(pf));
fclose(pf);
return 0;
}
fputs原型
int fputs(const char *string, FILE *stream);
代码如下(示例):
int main()
{
FILE* pf = fopen("in.txt", "w");
char* s = "hello world";
fputs(s, pf);//将s中的内容输出到pf指向的文件中
fclose(pf);
return 0;
}
运行结果如下,此时"in.txt"已经写入了"hello world"。
fgets原型:
char* fgets(char* string, int n, FILE* stream);
即从stream流中读入数据到string中,一次最多读n-1个(因为最后一个字符应该被置为’\0’)。
代码如下(示例):
int main()
{
FILE* pf = fopen("in.txt", "r");
char s[1024] = { 0 };
fgets(s, 1023, pf);
printf("%s\n", s);
fclose(pf);
return 0;
}
函数原型如下:
int fseek ( FILE * stream, long int offset, int origin );
//偏移量 起始位置
参数中的offset可以为负值,表示负向偏移
第三个参数origin设定从文件的哪里开始偏移,可能取值为:
SEEK_SET: 文件开头
SEEK_CUR: 当前位置
SEEK_END: 文件结尾
这个函数是用来定位函数指针的,定位好位置后,可用顺序读写的函数读或写内容。
代码如下(示例):
int main()
{
//in.txt中的内容为hello world
FILE* pf = fopen("in.txt", "r");
fseek(pf, 4, SEEK_SET);//将文件指针从文件开头向后4个位置
printf("%c\n", fgetc(pf));
fclose(pf);
return 0;
}
该函数可让文件指针回到文件的起始位置
函数原型为
void rewind ( FILE * stream );
代码如下(示例):
int main()
{
FILE* pf = fopen("in.txt", "r");
fseek(pf, 4, SEEK_SET);
printf("%c\n", fgetc(pf));
rewind(pf);
printf("%c\n", fgetc(pf));
fclose(pf);
return 0;
}
ueditor1.2.1修改超链接默认值 首先超链接的文件是在ueditor目录中的dialogs目录...
在调试网站后台时,遇见用EWEBEDITOR编辑内容时,不能从其他文件来源粘贴到里面. 1...
html5以及jQuery实现本地图片上传前的预览,效果类似如下: 选择图片前的页面: ...
在刚刚过去的 Flutter Engage 活动上,我们正式发布了 Flutter 2 : 为任何平台创...
近年来使用H5框架开发APP非常火爆前有mui框架后有uniapp这些框架使得我们开发app...
云计算发展有几十年的历史了随着科技的进步和发展云技术慢慢渗透到各行各业企业...
% function WriteToFile(FileName, Contents, Append) on error resume next if ...
图片来自 Pexels 现象与问题 ORDER BY 排序后,用 LIMIT 取前几条,发现返回的结...
我们在进行前端开发中必然会遇到PC与移动端的适配,面对这样的问题有些公司会准...
IT之家3月21日消息外媒 MSPoweruser 报道,尽管微软做出了努力,但仍有数千台内...