目录
一、为什么使用文件
在使用程序时,我们可以给程序中增加、删除数据,此时数据是存放在内存中;当程序退出时,程序中原本的数据就自然不存在了,等下次运行程序时,我们又得重新录入数据,如果我们使用这样的程序工作,会非常影响我们的工作效率。所以我们需要一个东西,帮我们把程序中的数据记录下来,并且只有我们自己选择删除数据的时候,数据才不复存在。
这就涉及到了数据持久化的问题,我们一般数据持久化的方法有,把数据存放在磁盘文件、存放到数据库等方式。使用文件我们可以将数据直接存放到电脑的磁盘上,做到了数据的持久化。
二、什么是文件
三、文件的打开和关闭
3.1文件指针
文件指针是访问文件的方式。每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的,取名FILE。
例如,VS2013编译环境提供的 stdio.h 头文件中有以下的文件类型申明。
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
FILE* pf;//文件指针变量
3.2文件的打开和关闭
文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
FILE *fopen( const char *filename, const char *mode );
//打开文件
int fclose( FILE *fp );
//关闭文件
在这里,filename 是字符串,用来命名文件,访问模式 mode 的值可以是下列值中的一个:
如果处理的是二进制文件,则需使用下面的访问模式来取代上面的访问模式:
文件使用方式
| 含义 | 如果指定文件不存在 |
“rb”(只读)
| 为了输入数据,打开一个二进制文件 | 出错 |
“wb”(只写)
| 为了输出数据,打开一个二进制文件 | 建立一个新的文件 |
“ab”(追加)
| 向一个二进制文件尾添加数据 | 出错 |
“rb+”(读写)
| 为了读和写打开一个二进制文件 | 出错 |
“wb+”(读写)
| 为了读和写,新建一个新的二进制文件 | 建立一个新的文件 |
“ab+”(读写)
| 打开一个二进制文件,在文件尾进行读和写 | 建立一个新的文件 |
实例代码:
/* fopen fclose example */
#include <stdio.h>
int main ()
{
FILE * pFile;
//打开文件
pFile = fopen ("myfile.txt","w");
//文件操作
if (pFile!=NULL)
{
fputs ("fopen example",pFile);
//关闭文件
fclose (pFile);
}
return 0;
}
四、文件的顺序读写
在文件操作中,我们将数据写入程序中称为“输出”,同理,我们读取程序数据时称为“输入”。
输入可以是以文件的形式或从命令行中进行。C 语言提供了一系列内置的函数来读取给定的输入,并根据需要填充到程序中。
输出意味着要在屏幕上、打印机上或任意文件中显示一些数据。C 语言提供了一系列内置的函数来输出数据到计算机屏幕上和保存数据到文本文件或二进制文件中。
功能
| 函数名 | 适用于 |
字符输入函数
| fgetc |
所有输入流
|
字符输出函数
|
fputc
|
所有输出流
|
文本行输入函数
| fgets | 所有输入流 |
文本行输出函数
| fputs | 所有输出流 |
格式化输入函数
| fscanf | 所有输入流 |
格式化输出函数
| fprintf | 所有输出流 |
二进制输入
| fread | 文件 |
二进制输出
| fwrite | 文件 |
五、文件的随机读写
5.1 fseek
以下是fseek函数的声明:
int fseek(FILE *stream, long int offset, int whence);
参数
- stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
- offset -- 这是相对 whence 的偏移量,以字节为单位。
- whence -- 这是表示开始添加偏移 offset 的位置。它一般指定为下列常量之一:
例子:
/* fseek example */
#include <stdio.h>
int main ()
{
FILE * pFile;
pFile = fopen ( "example.txt" , "wb" );
fputs ( "This is an apple." , pFile );
fseek ( pFile , 9 , SEEK_SET );
fputs ( " sam" , pFile );
fclose ( pFile );
return 0;
}
5.2 ftell
long int ftell(FILE *stream);
这里参数stream 是指向 FILE 对象的指针,该 FILE 对象标识了流。
例子:
/* ftell example : getting size of a file */
#include <stdio.h>
int main ()
{
FILE * pFile;
long size;
pFile = fopen ("myfile.txt","rb");
if (pFile==NULL) perror ("Error opening file");
else
{
fseek (pFile, 0, SEEK_END); // non-portable
size=ftell (pFile);
fclose (pFile);
printf ("Size of myfile.txt: %ld bytes.\n",size);
}
return 0;
}
5.3 rewind
rewind函数能够让文件指针的位置回到文件的起始位置。
以下是rewind函数的声明。
void rewind(FILE *stream);
例子:
/* rewind example */
#include <stdio.h>
int main ()
{
int n;
FILE * pFile;
char buffer [27];
pFile = fopen ("myfile.txt","w+");
for ( n='A' ; n<='Z' ; n++)
fputc ( n, pFile);
rewind (pFile);
fread (buffer,1,26,pFile);
fclose (pFile);
buffer[26]='\0';
puts (buffer);
return 0;
}