对于Linux程序员来说,对文件的IO操作是应用编程的基础内容,也是必须掌握的技能;下面作者通过两个基本概念和四个函数,来解析对文件的基本操作;
首先要明白两个基本的概念;文件和IO;
1.文件:文件指的是同类型数据的集合; 在linux中有一个重要思想;一切皆文件;也是说在Linux系统中把所有的文件、设备、内存等都当做文件来看待;因为这个思想的存在,所有在Linux系统中对设备及文件的操作方式都是一样的。Linux中把文件分为七种类型,分别是普通文件、设备文件(块设备和字符设备)、目录文件、管道文件、链接文件(符号链接文件),套接字;我们主要以普通文件来学习;
2. IO: IO是input和output的简写,也就是指的输入和输出;对于Linux系统来讲;输入及输出主要是从程序的角度来看的,因为程序员的主要的工作就是使用程序来处理数据; 所以输入指的就是把数据输入到程序中,输出值指的是从程序中输出数据;一般情况下,输入主要使用键盘,键盘也叫标准输入,而输出的结果主要显示在屏幕上,屏幕也就是标准输出;除了标准输入和标准输出外,还有一个标准文件——标准错误输出,它指的是当程序与运行或出错时,结果也会显示到屏幕上; 实际中,我们的数据输入并不一定要从键盘中输入,输出也不是只能输出到屏幕上;我们可以从文件、内存中输入数据到程序,也可以从程序中输出数据到文件及内存中;
在此文中,输入/输出都是对文件而言;
了解上面两个概念的有什么作用呢?作用就是你了解了我们操作对象是——文件;同时了解对文件进行的操作——数据的输入及输出;
那么,我们操作文件的一般思路是什么?思考1分钟钟再往下看!
操作一个文件时无非就以下三个步骤:
第一:打开文件;
第二:操作文件;
第三:关闭文件;
就是这么简单,你在之前的生活经历中早就掌握文件的操作思路了;问题在于,在Linux中,怎么打开、操作、关闭文件?答案是用对应的函数操作,所以IO的学习除了了解基本概念外,就是学习函数的的使用。
我先以标准IO 为例:我们通过四个函数来解析基本的操作思路;
标准IO中打开文件用 fopen()函数;原型为 FILE *fopen(const char *path, const char *mode);从原型中可以看出,fopen()有两参数;形参const char *path对应就是我需要打开的文件名称,包括文件的路径名称;const char *mode指的是打开文件后我们要对文件进行项什么样的操作? 是读、写、还是添加的写?参数如下:
mode 的参数有一些固定值;
r ——只读方式打开,
r+ ——读写方式打开,
以上两个参数必须要求文件存在;
w ——只写方式打开,
w+ ——读写方式打来;
使用以上两个参数时;若文件存在,则会清空文件,再写入具体数据!若文件不存在,则创建文件再写入数据;
a —— 以只写方式打开;
a+ —— 以读写方式打开;
以上两个参数使用时,若文件存在,则在后面添加数据,若文件不存在,则创建再写入数据;
上面的6个参数就是mode 可以写入的全部值;(都是单独使用的)
在fopen前有一个FILE *; 它是什么呢?当我们创建一个打开一个文件时,就会创建一个FILE 结构体描述改文件,或者说是创建一个FILE文件结构体和实际的文件关联起来;之后对FILE * 变量的操作就是对文件的操作;FILE 结构体也称为流;
标准IO关闭文件的函数是 fclose()函数,原型为:int fclose(FILE *fp);
只要把对应的文件流变量传给fclose()就可以了;
我们先来看一个fopen()函数的例子;
#include <stdio.h>
int main(int argc,char *argv[])
{
FILE *fp;
if(argc !=2)
{
printf("usage %s <filename>\n",argv[0]);
exit(1);
}
fp = fopen(argv[1],"w");
if(fp == NULL)
{
perror("perror");
exit(1);
}
fclose(fp);
return 0;
}
上面就是一个简单的打开文件的程序;
接下来要做的事就是怎么去操作文件?
文件的操作分两种方式,对文件进行读,或者对文件进行写!
读写的函数比较多,作者以fgets()和fputs()为例来讲解如何对文件进行读写操作;首先是fgets(); 它的主要作用是从文件流中读取数据,原型: char *fgets(char *s, int size, FILE *stream);对应的参数从后往前看,FILE *stream 指的是要读取的文件流,也会是要从此文件中读取数据;每次读的大小对应 int size ,并把数据存放到 char *s 对应的地址,成功会返回读到的字节数, 失败返回NULL;
下面时fgets()的实例程序:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *fp;
char buf[20];
if(argc !=2)
{
printf("usage %s <filename>\n",argv[0]);
exit(1);
}
fp = fopen(argv[1],"r");
if(fp == NULL)
{
perror("fopen failed");
exit(1);
}
while (fgets(buf, 20, fp) !=NULL)
{
printf("%s",buf);
}
fclose(fp);
return 0;
}
上面的程序中关于fgets()使用, 程序每次从fp对应的文件中读取19个字节数据并存在在buf中,并且在屏幕上打印出来;直到数据读完为止;
那么,如果想从一个文件中读取数据并写到另一个文件中,该怎么做?这就可以在上面的程序基础上添加一个函数的fputs();它的原型:int fputs(const char *s, FILE *stream); 对应的参数FILE *stream 是被写入的文件,也就是把数据写入此文件中;const char *s 是需要写入的数据; 实现从一个文件中读取数据并写到另一个文件中的程序就可以这样做;
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
FILE *read_fp,*write_fp;
char buf[10];
if(argc !=3)
{
printf("usage %s <read_filename> <write_filename>\n",argv[0]);
exit(1);
}
read_fp = fopen(argv[1],"r");
if(read_fp == NULL)
{
perror("read_fopen failed");
exit(1);
}
write_fp = fopen(argv[2],"w");
if(write_fp == NULL)
{
perror("write_fp fopen failed");
exit(1);
}
while(fgets(buf, 10, read_fp) !=NULL)
{
fputs(buf, write_fp);
}
fclose(read_fp);
fclose(write_fp);
return 0;
}
通过上面的概念及函数的使用,我们解析了标准IO中对文件的基本操作,当然,对文件的操作函数还有很多,但操作思路基本一样;读者可以以此为突破口进行更深入的学习。