文件_文件服务器 - CSDN
精华内容
参与话题
  • C语言对文件的操作

    万次阅读 多人点赞 2018-12-20 23:08:52
    前言在谭浩强的C语言设计的第10张讲了有关文件的知识, 以往我们写的C程序的数据都是由键盘输入的 现在我们要对文件进行操作。 文件是操作系统的基本单位。是我们专业领域的重要的一部分。 就拿我们的编译器来说...

    前言在谭浩强的C语言设计的第10张讲了有关文件的知识,
    以往我们写的C程序的数据都是由键盘输入的
    现在我们要对文件进行操作。

    文件是操作系统的基本单位。是我们专业领域的重要的一部分。
    就拿我们的编译器来说,我们写了一个程序,成功的运行了,编译系统会主动的生成3个文件如下图
    在这里插入图片描述

    它们分别是源程序文件.c
    目标文件.o
    可执行文件.exe

    在实际的情况下,常常要把一些数据输出到磁盘上保存起来,在需要时送入内存之中这就需要我们用到磁盘文件。

    1.文件名
    一个文件要有一个唯一的文件标识以便识别和引用,分别为
    1.路径(用来找到文件)
    2.名称(识别是什么)
    3.后缀(文件的格式或属性)

    在这里插入图片描述

    2.文件的分类
    书上将文件分成两类,分别是
    ASCII文件二进制文件
    1.ASCII文件我们在刚刚接触c语言时就了解了ASCII标,每个特定的数代表一个字符,那么将字符形式的文件就是ASCII文件,也称为文本文件,每个字节存放一个字符的ASCII值。
    2.二进制文件
    数据在内存中是以二进制形式存储的(因为CPU只认识0和1),如果不加转换的输出到外存,就是二进制文件。也称之为映像文件
    (因为从二进制转换到ASCII需要一定的时间,占的空间也更多,加之二进制文件的实用优点,我们生活中常用二进制的文件。)

    3.缓冲区概念
    我们都知道,在计算机的存储设备中,CPU的缓存速度是最快的,其次是显卡的显存,DDR5的显存早就已经普及,并有被淘汰之势,再次是内存,就在这几年DDR4的内存才开始广泛的使用,最慢的就是我们的硬盘(磁盘),机械硬盘的转速很慢,最快的速度也只有200多MB一秒,尽管我们现在普遍用上了固态硬盘,还是M.2协议的,但是和内存的差距依旧很大。因为两者的差距太大,就必须在数据写入磁盘时就有必要在内存中开辟一片缓冲区(所以缓冲区不是什么高大上的东西)

    4.文件类型指针
    回顾前面的知识,指针必须要有基类型(指向),如int p,floatp…。
    那么顾名思义文件指针就是指向文件的,其实文件在C语言中是,一种结构体
    也就是和结构体指针是一样的。
    以下是文件结构体的定义,结构体的名称为FILE。

    tpyedef struct
    {  short level;      //缓冲区满或空的程度
    
       unsigned flags;   //文件状态标志
       
       char fd;          //文件描述符
       
       unsigned char hold;  //如缓冲区无内容不读取字符
       
       short bsize;            //缓冲区的大小
       
       unsigned char*buffer;     //数据缓冲区的位置
       
       unsigned char*curp;      //文件位置标记指针当前的指向
       
       unsigned istemp;        //临时文件指示器
       
       short token;         //用于有效性检查
       }FILE
       //这是TC2.0中的定义
    
    #ifndef _FILE_DEFINED
    struct _iobuf {
    
         char *_ptr; //文件输入的下一个位置
                int   _cnt;  //当前缓冲区的相对位置
                char *_base;  //指基础位置(即是文件的其始位置) 
                int   _flag;  //文件标志
                int   _file;   //文件的有效性验证
                int   _charbuf;  //检查缓冲区状况,如果无缓冲区则不读取
                int   _bufsiz;   //缓冲区大小
                char *_tmpfname;  //临时文件名
            };
    typedef struct _iobuf FILE;
    #define _FILE_DEFINED
    #endif  //这是VC6。0里定义
    

    当然我们不必去深究其中的作用(会写标准库定义的人不知道比我们高到哪里去了)
    但要稍微了解一下

    下面介绍关于文件的函数
    1.打开与关闭文件函数
    fopen 打开文件函数 (成功打开后指向该流的文件指针就会被返回,失败返回NULL)
    fclose 关闭文件函数
    引用方法

    fopen(文件名,使用文件方式)//文件名是一个字符串,使用方式需要加双引号,
    

    为了使文件指针与文件建立联系我们要将函数返回的指针给我们的文件指针
    像这样

    FILE*fp;
    fp = fopen("test.txt","r");//以读的方式打开默认路径下一个叫test的文本文件
    

    可以说这样就将fp指向了test这个文件。
    既然文件的使用方式,我们就要全面的了解

    文件使用方式 含义 如果指定的文件不存在
    r(只读) 输入数据,打开一个已存在文本文件 出错
    w(只写) 输出数据,打开一个文本文件 建立一个新文件
    a(追加) 向文本文件尾添加数据 出错
    rb(只读) 输入数据,打开一个2进制文件 出错
    wb(只写) 输出数据,打开一个2进制文件 建立新文件
    r+(读写) 读写,文本文件 出错
    w+(读写) 读写,文本文件 建立新文件
    a+(读写) 读写,文本文件 出错
    rb+(读写) 读写,二进制文件 出错
    wb+(读写) 读写,二进制文件 建立新文件
    ab+(读写) 读写二进制文件 出错

    这里我们来用一个小程序演示一下
    我现在编译器默认路径下建立一个空的文本文件test
    在这里插入图片描述

    #include <stdio.h>
    int main()
    {
         FILE*p; //设置一个文件指针
    
         char ch; //定义一个字符变量
    
         if((p=fopen("test.txt","w"))==NULL) //打开一个叫test的文本文件,以只写的方式,当   出错时,即返回值为NULL时,输出错误信息
         {
                printf("ERROR");
    
               exit(0); //关闭所有文件,终止正在执行的程序
          }
    
          for(;ch!='\n';) //输入ch知道输入空格。
          {
                scanf("%c",&ch);
                 fputc(ch,p); //将字符ch写入p所指向的文件
          } 
    fclose(p);//关闭文件
    }
    

    在这里插入图片描述我们再到默认路径打开test.txt。

    在这里插入图片描述可以看到我们在键盘里输出的Merry Christmas已经被写入了test之中

    下面我们来读取这个文件里的信息
    我们只需要将程序稍微修改一下就可以

    #include <stdio.h>
    int main()
    {
    	FILE*p;
    	
    	char ch;
    	
    	if((p=fopen("test.txt","r"))==NULL)  //以只读的方式打开test。
    	{
    		printf("ERROR");
    		
    		exit(0);
    	}
    	
    	for(;ch!='\n';)
    	{
    		ch=fgetc(p);   //ch得到p所指文件中的每一个字符
    		putchar(ch);     //将得到的字符输出到屏幕
    	}
    	
    
    	fclose(p);	//关闭文件
    }
    

    下面是截图
    在这里插入图片描述

    值得注意的是,在我们向文件写入的时候会将原有的内容清空再进行写入
    请看我们再对test进行写入
    这次我输入了happy
    在这里插入图片描述
    再到默认路径下打开text文件
    在这里插入图片描述

    可以看到我们的Merry Christmas被清除了并用我们的happy写入了文件
    如果要对文本文件 进行写入并保留原有内容,就要用追加的方式进行

    	if((p=fopen("test.txt","a"))==NULL) //只需将w改为a即可
    

    下面我们再进行写入
    在这里插入图片描述
    再打开test文件
    在这里插入图片描述

    5.顺序读写数据文件

    1.读写字符函数
    读字符 fgetc

    fegrtc(文件指针)   //从指针所指向的文件中读入一个字符
    

    写字符fputc

    fputc(ch,fp)    //把字符变量ch写到fp所指向的文件中去
    

    我们在上一个例子中就使用了这俩个函数,为了有更深刻的印象。
    我以一个文件复制的程序来中举例
    下面是源码

    #include <stdio.h>
    int main()
    {
    	FILE*p1,*p2;    //设置2个文件指针
    	
    	char filename[30],filename1[30],ch;  //设置2个字符数组用来输入文件名用
    	
    	printf("请输入要复制的文件名\n"); 
    	
    	gets(filename);      //输入文件名
    	
    	printf("请输入复制后的文件名:\n");
    	
    	gets(filename1);     //输入文件名
    	
    	if((p1=fopen(filename,"rb"))==NULL)  //打开被复制的文件
    	{
    		printf("ERROR");
    		
    		exit(0);
    	}
    	if((p2=fopen(filename1,"wb"))==NULL) //写入要复制的文件名
    	{
    		printf("ERROR");
    		
    		exit(0);
    	}
    	
    	while(!feof(p1))    //用一个检查文件是否结束的函数来判断
    	{
    		ch=fgetc(p1);   //读出每一个p1指向的文件中的字节,把ch写入到p2指向的文件中去,如果没有p2文件,则会建立一个以filename1字符数组命名的文件
    		
    		fputc(ch,p2);
    	} 
    	
    	printf("复制成功"); 
    	
    	fclose(p1);   //用完之后,为了避免不必要的操作干扰读写,要关闭文件,即断掉文件指针与文件的联系
    	fclose(p2);
    	
    	
    	
    }
    

    下面是运行效果,我的默认路径中有一张名为23.jpg的图片文件
    在这里插入图片描述运行程序
    写入如下
    在这里插入图片描述再去查看默认路径
    就多了一张叫jaychou的jpg图片
    在这里插入图片描述下面就要介绍检测文件是否介绍的函数
    feof(end of file)

    feof(文件指针)   //当文件结束时返回非0值,当文件未结束时返回0
    

    再看刚才的循环语句

    while(!feof(fp))//当返回值为0的时候执行循环,返回值非0的时候就结束循环
    

    当然我们也可以用这个程序来复制文本文件
    在这里插入图片描述在这里插入图片描述

    当然对于文本文件文件可以不用二进制的方式处理
    我们也可以把刚才的循环语句换成如下

    while(!(ch=fgetc(fp))==EOF)      //我们的EOF和NULL一样都是标准库里的宏定义EOF就是-1,NULL代表0
    

    那么这个-1又代表了什么
    文件的所有有效字符后有一个文件尾标志,当读完全部的字符后,文件读写位置标记就会指向最后一个字符的后面的结束字节(里面存放了-1),如果再读取就会读出-1
    在文本文件中,数据都是以字符的ASCII代码值的形式存放。我们知道,ASCII代码值的范围是0~127,不可能出现-1,因此可以用EOF作为文件结束标志。

    WARNING二进制文件因为是以二进制形式保存的所以不能以字符的方式来存取的,所以不应用刚才的方式对二进制文件进行写入。

    同样
    我们也有字符串的读写文件

    函数名 调用形式 功能 返回值
    fgets fgets(str,n,fp) 从fp指向的文件读入一个长度为n-1的字符串,存放到字符数组str中去 成功返回地址str,失败返回NULL
    fputs fputs(str,fp)) 把str所指向的字符串写入fp所指向的文件中 成功返回0,失败返回非零

    下面来举个例子
    现在test中写如下内容
    在这里插入图片描述我们用fgets函数读取出来并输出上面的文字

    #include <stdio.h>
    #define LEN 40
    int main()
    {
    	FILE*fp;
    	
    	char filename[LEN],string[30]; //定义一个字符数组来存储文件里的信息
    	
    	printf("请输入要打开的文件名");
    	
    	gets(filename);
    	
    	if((fp=fopen(filename,"r"))==NULL)   //以只读的方式打开文件打开文件
    	{
    		printf("ERROR");
    		exit(0);
    	} 
    	
    	fgets(string,20,fp);  //将fp所指的文件中的20字符读取给字符串string
    	
    	fclose(fp);   //关闭文件
    	
    	puts(string);  //以字符串形式输出string
    	
    }
    

    在这里插入图片描述

    6.用格式化的方式读写文本文件
    在我们以前的输出输入之中,常用scanf和printf函数,我们的格式化读写函数和他们类似

    名称 引用方式
    fprintf fprintf(文件指针,格式字符串,输出列表)
    fscanf fscanf(文件指针,格式字符串,输入列表)
    #include <stdio.h>
    int main()
    {
    	int i=3;float j=4.567;char string[20];
    	
    	FILE*fp;
    	
    	if((fp=fopen("test.txt","r+"))==NULL)   //以读写的方式打开test
    	{
    		printf("ERROR");
    		exit(0);
    	}
    	
    	fscanf(fp,"%s",string);  把其中的字符串写入字符数组string中
    	
    	puts(string); //输出由文件中写入的字符串
    	
    	
    	fprintf(fp,"%3d,%6.4f",i,j);  //以%3d,%6.4的格式输入整形变量i和浮点型变量j
    	
    	fclose(fp);   //关闭文件
    	
    } 
    

    在这里插入图片描述
    再去默认路径中打开test文件
    在这里插入图片描述
    7.用二进制方式向文件读写一组数据

    其实我们上面的复制图片的例子也是对二进制文件的读写,在这里有一组专门的二进制文件读写函数
    分别是
    fread
    fwrite

    名称 引用方式
    fread fread(buffer,size,count,fp)
    fwrite fwrite(buffer,size,count,fp)

    也被称为数据块读写

    函数原型size_t fread ( void *buffer, size_t size, size_t count, FILE *stream)

    参 数
    buffer
    用于接收数据的内存地址(是一个指针,无论输出输入都是首地址)
    size
    要读的每个数据项的字节数,单位是字节
    count
    要读count个数据项,每个数据项size个字节.
    stream
    文件指针

    数据块读写多用于结构体变量的读写(因为结构体所占的字符数是不规则的)
    下面举一个例子

    #include <stdio.h>
    #define LEN 15   //结构体中字符串的长度
    #define NUM 8    //要输入数据学生的个数
    struct Student    //定义学生结构体
    {
    	char name[LEN];
    	
    	int num;
    	
    	int age;
    	
    	char add[LEN];
    }Stud[NUM];      //将数据先存放在结构体数组之中
    int main()
    {
    	FILE*fp;
    	
    	int i;
    	
    	if((fp=fopen("stduent","wb"))==NULL)  //建立一个叫student的文件以二进制形式进行打开进行写入操作,
    	{
    		printf("ERROR");
    		
    		exit(0);
    	}
    	
    	printf("请输入学生数据\n");
    	
    	for(i=0;i<NUM;i++)   //
    	{
    		scanf("%s%d%d%s",&Stud[i].name,&Stud[i].num,&Stud[i].age,&Stud[i].add);//输入学生数据信息
    	}
    	
    	for(i=0;i<NUM;i++)
    	{
    		if(fwrite(&Stud[i],sizeof(struct Student),1,fp)!=1)//每次写一个结构体变量所占的字节,将输入的数据写入文件
    		{
    			printf("write error");
    		}
    	}
    	
    	fclose(fp);	//关闭文件
    }
    

    完成输入如图
    在这里插入图片描述当我们去默认路径找到student文件,发现并不是文本文件,用文本文本的格式打开会看见二进制的源码转化出的乱码
    在这里插入图片描述我们再改变一下以上的代码,将student的文件中的学生数据读取出来

    按照上面的输入稍微修改一下即可
    下面是代码

    #include <stdio.h>
    #define LEN 15
    #define NUM 8 
    struct Student
    {
    	char name[LEN];
    	
    	int num;
    	
    	int age;
    	
    	char add[LEN];
    }Stud[NUM];
    int main()
    {
    	FILE*fp;
    	
    	int i;
    	
    	if((fp=fopen("student","rb"))==NULL)  //以二进制的方式读取
    	{
    		printf("ERROR");
    		
    		exit(0);
    	}
    	
    	printf("姓名 学号 年龄 地址\n");
    	
    	
    	
    	for(i=0;i<NUM;i++)   //将数据每次一个结构体变量所占字节的个数的数据赋给结构体变量
    	{
    		if(fread(&Stud[i],sizeof(struct Student),1,fp)!=1)
    		{
    			printf("read error");
    		}
    	}
    	
    	for(i=0;i<NUM;i++)  //输出结构体变量的各个成员,输出数据
    	{
    		printf("%-10s%4d%4d%-15s",Stud[i].name,Stud[i].num,Stud[i].age,Stud[i].add);
    		printf("\n");
    	}
    	
    	fclose(fp);	//关闭文件
    }
    

    下面是运行截图
    在这里插入图片描述不用从键盘输入数据,将文件中的数据读取出来

    PS(当文件不在编译器默认的路径时,要在文件名初加上文件的路径,
    若一个文件为D:\data\student,我们要输入它的路径如下
    D:\data\student因为只是一个反斜杠的话会被和后面的字符被认为是转义字符处理,
    这也是我们的老师在我们刚学C语言时就教过的)

    8.随机读写数据文件

    1.文件位置标记即其定位

    文件位置标记其实是一个文件中的一个指针
    在我们的顺序读写当中,都是一个字符一个字符的读出有写入
    没有出现跳跃的情况,
    但在实际使用的过程中,我们不许要每次都要把文件全部都读一遍
    只需要稍微的改动某些数据,
    下面由本人这个灵魂画师来画一个图演示一下
    在这里插入图片描述
    文件位置标记的定位

    rewind 功能是将文件内部的指针重新指向一个文件的开头

    rewind(文件指针);
    

    现在把上面的代码改一下

    #include <stdio.h>
    #define LEN 15
    #define NUM 8 
    struct Student
    {
    	char name[LEN];
    	
    	int num;
    	
    	int age;
    	
    	char add[LEN];
    }Stud[NUM];
    int main()
    {
    	FILE*fp,*fp1;
    	
    	int i;
    	
    	if((fp=fopen("student","rb"))==NULL)
    	{
    		printf("ERROR");
    		
    		exit(0);
    	}
    	if((fp1=fopen("CSDN","wb"))==NULL)   //以写入的方式打开一个文件
    	{
    		printf("ERROR");
    		
    		exit(0);
    	}
    	
    	printf("姓名     学号   年龄     地址\n");
    	
    	
    	
    	for(i=0;i<NUM;i++)    //把文件中的数据读入结构体数组的元素
    	{
    		if(fread(&Stud[i],sizeof(struct Student),1,fp)!=1)
    		{
    			printf("read error");
    		}
    	}
    	
    	rewind(fp);   //重置文件指针
    	
    	for(i=0;i<NUM;i++)  //写入新的文件中
    	{
    		if(fwrite(&Stud[i],sizeof(struct Student),1,fp1)!=1)
    		{
    			printf("read error");
    		}
    	}
    	
    	for(i=0;i<NUM;i++)  //输出文件数据
    	{
    		printf("%-10s%4d%4d%15s",Stud[i].name,Stud[i].num,Stud[i].age,Stud[i].add);
    		printf("\n");
    	}
    	
    	fclose(fp);	
    	fclose(fp1);
    }
    

    运行如前面的图一样,默认路径中出现了一个名为CSDN的文件,里面存放着学生的数据

    fseek函数,文件指针位置函数
    引用方法为

    fseek(文件指针,位移量,起始点)

    起始点有3种情况,分别是0,1,2
    如表

    起始点 名字 用数字代表
    文件开始位置 SEEK_SET 0
    文件当前位置 SEEK_CUR 1
    文件末尾位置 SEEK_END 2

    位移量是long形数据要在结尾加上L

    fseek(fp,100L,0);//将文件位置标记向前移动到离文件开头100个字节处
    fseek(fp,50L,1);//将文件位置标记前移到离当前位置50个字节处
    fseek(fp,-10L,2);//将文件位置标记从文件末尾后退10个字节
    

    在上面的代码出修改一下

    	for(i=0;i<NUM;i+=2)
    	{
    		fseek(fp,i*sizeof(struct Student),0);//跳过每次移动2个结构体所占的字节
    		
    		printf("%-10s%4d%4d%15s",Stud[i].name,Stud[i].num,Stud[i].age,Stud[i].add);
    		printf("\n");
    	}
    

    我们就实现了只输出部分的数据
    在这里插入图片描述ferror函数
    在调用各种输入输出函数(如 putc.getc.fread.fwrite等)时,如果出现错误,除了函数返回值有所反映外,还可以用ferror函数检查。 它的一般调用形式为 ferror(fp);如果ferror返回值为0(假),表示未出错。如果返回一个非零值,表示出错。应该注意,对同一个文件 每一次调用输入输出函数,均产生一个新的ferror函 数值,因此,应当在调用一个输入输出函数后立即检 查ferror函数的值,否则信息会丢失。在执行fopen函数时,ferror函数的初始值自动置为0。
    clearerr
    clearerr的作用是使文件错误标志和文件结束标志置为0.假设在调用一个输入输出函数时出现了错误,ferror函数值为一个非零值。在调用clearerr(fp)后,ferror(fp)的值变为0。
    只要出现错误标志,就一直保留,直到对同一文件调用clearerr函数或rewind函数,或任何一个输入输出函数。

    感想:这是我的C语言博客的结束篇,在这2个多月的学习中,有困难也有喜悦,从一个小白,渐渐打开编程的一角,C语言交给我的思想,会帮我开起我的程序人生。
    farewell C

    展开全文
  • 文件的概念

    千次阅读 2018-02-11 11:11:49
    ---------文件的定义:  文件是操作系统中的一个重要概念。文件是以计算机硬盘为载体存储在计算机上的信息集合,文件可以是文本文档、图片、程序,等等。在系统运行时,  计算机以进程为基本单位进行资源的调度...

    ---------文件的定义:

                文件是操作系统中的一个重要概念。文件是以计算机硬盘为载体存储在计算机上的信息集合,文件可以是文本文档、图片、程序,等等。在系统运行时,

          计算机以进程为基本单位进行资源的调度和分配而在用户进行的输入、输出中,则以文件为基本单位。大多数应用程序的输入都是通过文件来实现的,

          其输出也保存在文件中,以便信息的长期存储及将来的访问。当用户将文件用于应用程序的输入、输出时,还希望可以访问文件、修改文件和保存文件等,实现

          文件的维护管理,这就需要系统提供一个文件管理系统,操作系统的文件系统就是用于实现用户的这些管理要求。

                从用户的角度看,文件系统是操作系统的重要部分之一。用户关心的是如何命名、分类和查找文件,如何保证文件数据的安全性以及对文件可以进行哪些操作

          等。而对其中的细节,如文件如何存储在辅存上、如何管理文件辅存区域等关心甚少。

                文件系统提供了与二级存储相关的资源的抽象,让用户能在不了解文件的各种属性、文件存储介质的特征以及文件在存储介质上的具体位置等情况下,方便快捷

          地使用文件。

                用户通过文件系统建立文件,提供应用程序的输入、输出,对资源进行管理。首先了解文件的结构,我们通过自底向上的方式来定义:

                (1)、数据项。数据项是文件系统中最低级的数据组织形式,可分为以下两种类型:

                             基本数据项:用于描述一个 对象的某种属性的一个值,如姓名、日期或证件号等,是数据中可命名的最小逻辑数据单位,即原子数据。

                             组合数据项:由多个基本数据项组成。

                (2)、记录。记录是一组相关的数据项的集合,用于描述一个对象在某方面的属性,如一个考生报名记录包括姓名、出生日期、报考学校代号、身份证等

                             一系列域。

                (3)、文件。文件是指由创建者所定义的一组相关信息的集合,逻辑上可分为有结构文件无结构文件两种。在有结构文件中,文件由一组相似记录组成,

                            如报考某学校的所有考生的报考信息记录,又称为记录式文件;而无结构文件则被看成是一个字符流,比如一个二进制文件或字符文件,又称为流式文件


                  虽然上面给出了结构化的表述,但实际上关于文件并无严格的定义。通常在操作系统中将程序和数据组织成文件。文件可以是数字、字母或二进制代码,基本

              访问单元可以是字节、行或记录。文件可以长期存储于硬盘或其他二级存储器中,允许可控制的进程间共享访问,能够被组织成复杂的结构


    -------文件属性:

             文件有一定的属性,这根据系统的不同而有所不同,但是通常都包括如下属性。

             (1)、名称。文件名称唯一,以容易读取的形式保存。

             (2)、标识符。标识文件系统内文件的唯一标签,通常为数字,它是对人不可读的一种内部名称。

             (3)、类型。被支持不同类型的文件系统所使用。

             (4)、位置。指向设备和设备上文件的指针。

             (5)、大小。文件当前大小(用字节、字或块表示),也可包含文件允许的最大值。

             (6)、保护。对文件进行保护的访问控制信息。

             (7)、时间、日期和用户标识。文件创建、上次修改和上次访问的相关信息,用于保护、安全和跟踪文件的使用。

     

               所有文件的信息都保存在目录结构中,而目录结构也保存在外存上。文件信息当需要时再调入内存。通常,目录条件包括文件名臣及其唯一标识符,而

        标识符定位其他属性的信息。


    --------文件的基本操作:

              文件属于抽象数据类型。为了恰当地定义文件,就需要考虑有关文件的操作。操作系统提供系统调用,它对文件进行创建、写、读、定位和截断。

              (1)、创建文件。创建文件有两个必要步骤,一是在文件系统中为文件找到空间;二是在目录中为新文件创建条目,该条目记录文件名称、在文件

                        系统中的位置及其其他可能信息。

              (2)、写文件。为了写文件,执行一个系统调动,指明文件名称和要写入文件的内容。对于给定文件名称,系统搜索文件目录以查找文件位置。系统

                       必须为该文件维护一个写位置的指针。每当发生写操作,便更新写指针。

              (3)、读文件。为了读文件,执行一个系统调用,指明文件名称和要读入文件块的内存位置。同样,需要搜索目录以找到相关目录项,系统维护一个

                      读位置的指针。每当发生读操作时,更新读指针。一个进程通常只一个文件读或写,所以当前操作位置可作为每个进程当前文件位置指针。由于

                     读和写操作都使用同一指针,节省了空间也降低了系统复杂度。

             (4)、文件重定位(文件寻址)。按某条件搜索目录,将当前文件位置设为给定值,并且不会读、写文件。

             (5)、删除文件。先从目录中找到要删除文件的目录项,使之称为空项,然后回收该文件所占用的存储空间。

             (6)、截断文件。允许文件所有属性不变,并删除文件内容,即将其长度设为 0 并释放其空间。

               补充:这6个基本操作可以组合到执行其他文件操作。例如,一个文件的复制,可以创建行文件、从旧文件读出并写入新文件。


    --------文件的打开与关闭:

                因为许多文件操作都涉及为给定文件搜索相关目录条目,许多系统要求在首次使用文件时,使用系统调用 open ,将指明文件的属性(包括该文件在外存上

           的物理位置)从外存拷贝到内存打开文件目录表的一个表目中,并将该表目的编号(或称为索引)返回给用户。操作系统维护一个包含所有打开文件信息的表

          (打开文件表,open-file table) 。当用户需要一个文件操作时,可通过该表的一个索引指定文件,就省略了搜索环节。当文件不再使用时,进程可以关闭它,

            操作系统从打开文件表中删除这一条目。

                大部分操作系统要求在文件使用之前就被显式打开。操作 open 会根据文件名搜索目录,并将目录条目复制到打开文件表。如果调用 open 的请求(创建、

            只读、读写、添加等)得到允许,进程就可以打开文件,而 open 通常返回一个指向打开文件表中的一个条目的指针。通过使用该指针(而非文件名)进行

           所有的 I / O 操作,以简化步骤并节省资源。

                注意,open 调用完成之后,操作系统对该文件的任何操作,都不再需要文件名,只需要 open 调用返回的指针。 


              整个系统表包含进程相关信息,如文件在磁盘的位置访问日期和大小。一个进程打开一个文件,系统打开文件表就会为打开的文件增加相应的条目。当另一个

        进程执行 open 时,只不过是在其进程打开表中增加一个条目,并指向整个系统表的相应条目。通常,系统打开文件表的每个文件时,还用一个文件打开计数器(Open

           Count ),以记录多少进程打开了该文件。每个关闭操作 close 则使得  Count  递减,当打开计数器为 0 时,表示该文件不再使用。系统将回收分配给该文件的内存空

        间等资源,若文件被修改过,则将文件写回外存,并将系统打开文件表中相应条目删除,最后释放文件的文件控制块(FCB)。


              每个打开文件都有如下关联信息:

             》》文件指针:系统跟踪上次读写位置作为当前文件位置指针,这种指针对打开文件的某个进程来说是唯一的,因此必须与磁盘文件属性分开保存。

             》》文件打开计数器:文件关闭时,操作系统必须重用其打开文件表条目,否则表内空间不够用。因为多个进程可能打开同一个文件,所以系统在删除打开文件条目

                    之前,必须等待最后一个进程关闭文件。该计数器跟踪打开和关闭的数量,当该计数为  0 时,系统关闭文件,删除该条目。

             》》文件磁盘位置:绝大多数文件操作都要求系统修改文件数据。该信息保存在内存中,以免为每个操作都从磁盘中读取。

             》》访问权限:每个进程打开文件都需要有一个访问模式(创建、只读、读写、添加等),该信息保存在进程的打开文件表中,以便操作系统能允许或拒绝之后的

                    I / O 请求。


              

          

          

                

       

           

        

               


                        

    展开全文
  • C语言文件操作详解

    万次阅读 多人点赞 2016-03-04 15:50:58
    C语言文件操作函数 函数介绍 文件打开与关闭操作 fopen():文件打开操作 头文件:stdio.h 函数定义:FILE *fopen(char *pname, char *mode) 函数说明:pname是文件名,mode是打开文件的方式 mode:"r" 打开一...

    C语言文件操作函数

    函数介绍

    文件打开与关闭操作

    fopen():文件打开操作

    头文件:stdio.h
    函数定义:FILE *fopen(char *pname, char *mode)
    函数说明:pname是文件名,mode是打开文件的方式
    mode:"r" 打开一个已经存在的文件文本,文件不存在则出错



    以“r+”的方式打开一个文件,会清空文件的原始内容,重新写入数据

    返回值:正常返回:FILE *一个指向文件在内存中的文件信息去的开头

    异常返回:NULL,表示打开操作不成功

    打开文件的作用是:
    (1)分配给打开文件一个FILE 类型的文件结构体变量,并将有关信息填入文件结构体变量;
    (2)开辟一个缓冲区;
    (3)调用操作系统提供的打开文件或建立新文件功能,打开或建立指定文件;
    FILE *:指出fopen是一个返回文件类型的指针函数;

     返回值
       正常返回:被打开文件的文件指针。
       异常返回:NULL,表示打开操作不成功。

     要说明的是:C语言将计算机的输入输出设备都看作是文件。例如,键盘文件、屏幕文件等。ANSI C标准规定,在执行程序时系统先自动打开键盘、屏幕、错误三个文件。这三个文件的文件指针分别是:标准输入stdin、标准输出stdout和标准出错 stderr。

     fclose():文件关闭

    函数定义int fclose(FILE *fp);

    函数说明:fp是一个以打开的文件的文件指针

    返回值:

    正常返回:0

    异常返回:EOF,表示文件在关闭时发生错误


    fgetc:读取一个字符

    函数定义:int fgetc(FILE *fp)

    函数说明:从fp中读取一个字符,作为返回值返回

    返回值:

    正常返回:返回读取字符的代码

    异常返回:返回EOF。例如:要从“写打开”的文件中读取一个字符时,会发生错误而返回一个EOF

    【例8.1】显示指定文件的内容。

    //程序名为:display.c
    //执行时可用:display filename1 形式的命令行运行。显示文件filename1中的内容。例如,执行命令行display display.c将在屏幕上显示display的原代码。
    
    //File display program.
    #include <stdio.h>
    void main(int argc,char *argv[]) //命令行参数
    {
        int ch;//定义文件类型指针
        FILE *fp;//判断命令行是否正确
        if(argc!=2)
        {
            printf("Error format,Usage: display filename1\n");
            return; //键入了错误的命令行,结束程序的执行
        }
        //按读方式打开由argv[1]指出的文件
        if((fp=fopen(argv[1],"r"))==NULL)
        {
            printf("The file <%s> can not be opened.\n",argv[1]);//打开操作不成功
            return;//结束程序的执行
        }
        //成功打开了argv[1]所指文件
        ch=fgetc(fp); //从fp所指文件的当前指针位置读取一个字符
        while(ch!=EOF) //判断刚读取的字符是否是文件结束符
        {
            putchar(ch); //若不是结束符,将它输出到屏幕上显示
            ch=fgetc(fp); //继续从fp所指文件中读取下一个字符
        } //完成将fp所指文件的内容输出到屏幕上显示
        fclose(fp); //关闭fp所指文件
    }



    fputc:写一个字符到文件中

    函数定义:int fputc(int ch, FILE*fp)

    函数说明:ch是一个整型变量,要写到文件的字符

    fp:文件指针,要写入的文件

    返回值:

    正常返回:要写入的字符的代码

    异常返回:返回EOF

    【例8.2】将一个文件的内容复制到另一个文件中去。

    //程序名为:copyfile.c
    //执行时可用:copyfile filename1 filename2形式的命令行运行,将文件filename1中的内容复制到文件filename2中去。
    //file copy program.
    #include <stdio.h>
    void main(int argc,char *argv[]) //命令行参数
    {
        int ch;
        FILE *in,*out; //定义in和out两个文件类型指针
        if(argc!=3) //判断命令行是否正确
        {
            printf("Error in format,Usage: copyfile filename1 filename2\n");
            return; //命令行错,结束程序的执行
        }
        //按读方式打开由argv[1]指出的文件
        if((in=fopen(argv[1],"r"))==NULL)
        {
            printf("The file <%s> can not be opened.\n",argv[1]);
            return; //打开失败,结束程序的执行
        }
        //成功打开了argv[1]所指文件,再
        //按写方式打开由argv[2]指出的文件
        if((out=fopen(argv[2],"w"))==NULL)
        {
            printf("The file %s can not be opened.\n",argv[2]);
            return; //打开失败,结束程序的执行
        }
        //成功打开了argv[2]所指文件
        ch=fgetc(in); //从in所指文件的当前指针位置读取一个字符
        while(ch!=EOF) //判断刚读取的字符是否是文件结束符
        {
            fputc(ch,out); //若不是结束符,将它写入out所指文件
            ch=fgetc(in); //继续从in所指文件中读取下一个字符
        } //完成将in所指文件的内容写入(复制)到out所指文件中
        fclose(in); //关闭in所指文件
        fclose(out); //关闭out所指文件
    }


    【例8.3】按十进制和字符显示文件代码,若遇不可示字符就用井号"#"字符代替之。

    //程序名为:dumpf.c
    //执行时可用:dumpf filename1 形式的命令行运行。
    // File dump program.
    #include <stdio.h>
    void main(int argc,char *argv[])
    {
        char str[9];
        int ch,count,i;
        FILE *fp;
        if(argc!=2)
        {
            printf("Error format,Usage: dumpf filename\n");
            return;
        }
        if((fp=fopen(argv[1],"r"))==NULL)
        {
            printf("The file %s can not be opened.\n",argv[1]);
            return;
        }
        count=0;
        do{
            i=0;
            //按八进制输出第一列,作为一行八个字节的首地址
            printf("%06o: ",count*8);
            do{
                // 从打开的文件中读取一个字符
                ch=fgetc(fp);
                // 按十进制方式输出这个字符的ASCII码
                printf("%4d",ch);
                // 如果是不可示字符就用"#"字符代替
                if(ch<' '||ch>'~') str[i]='#';
                // 如果是可示字符,就将它存入数组str以便形成字符串
                else str[i]=ch;
                // 保证每一行输出八个字符
                if(++i==8) break;
            }while(ch!=EOF); // 遇到文件尾标志,结束读文件操作
            str[i]='\0'; // 在数组str加字符串结束标志
            for(;i<8;i++) printf(" "); // 一行不足八个字符用空格填充
            printf(" %s\n",str); // 输出字符串
            count++; // 准备输出下一行
        }while(ch!=EOF); // 直到文件结束
        fclose(fp); // 关闭fp所指文件
    }
    


    fgets():从文件中读取一个字符串

    函数定义:char *fgets(char *str, int n, FILE *fp)

    函数说明:由fp指出的文件中读取n-1个字符,并把他们存放到有str指出的字符数组中区,最后加上一个由字符串结束符'\0'

    参数说明:str:接受字符串的内存地址,可以是数组别名,也可以是指针

    n:指出要读取的字符的个数

    fp:这个是文件指针,指出要从中读取字符的文件

    返回值:

    正常返回:字符串的内存首地址,即str的值

    异常返回:返回一个NULL值,此时应当用feof()或ferror()函数来判别是读取到了文件尾,还是发生了错误。

    fputs():写入字符串到文件中去

    函数定义:把由str之处的字符串写入到fp所指的文件中去

    函数说明:

    str:之处要写入到文件中去的字符串,不包括最后的'\0'

    fp:这个是文件指针,之处字符串要写入到的文件指针

    返回值:

    正常返回:写入到的文件的字符个数,即字符串的长度

    非正常返回:返回一个NULL值,此时应当用feof()或ferror()函数来判别是读取到了文件尾,还是发生了错误。

    5.实例

    【例8.4】以下程序将一个文件的内容附加到另一个文件中去。

    //程序名:linkfile.c
    //执行时可用:linkfile filename1 filename2形式的命令行运行,将文件filename2的内容附加在文件filename1之后。
    // file linked program.
    #include <stdio.h>
    #define SIZE 512
    void main(int argc,char *argv[])
    {
        char buffer[SIZE];
        FILE *fp1,*fp2;
        if(argc!=3)
        {
            printf("Usage: linkfile filename1 filename2\n");
            return;
        }
        // 按追加方式打开argv[1] 所指文件
        if((fp1=fopen(argv[1],"a"))==NULL)
        {
            printf("The file %s can not be opened.\n",argv[1]);
            return;
        }
        if((fp2=fopen(argv[2],"r"))==NULL)
        {
            printf("The file %s can not be opened.\n",argv[2]);
            return;
        }
        // 读入一行立即写出,直到文件结束
        while(fgets(buffer,SIZE,fp1)!=NULL)
            printf("%s\n",buffer);
        while(fgets(buffer,SIZE,fp2)!=NULL)
            fputs(buffer,fp1);
        fclose(fp1);
        fclose(fp2);
        if((fp1=fopen(argv[1],"r"))==NULL)
        {
            printf("The file %s can not be opened.\n",argv[1]);
            return;
        }
        while(fgets(buffer,SIZE,fp1)!=NULL)
            printf("%s\n",buffer);
        fclose(fp1);
    }


    E. 往文件中写格式化数据

    1.函数原型

    int fprintf(FILE *fp,char *format,arg_list)

    2.功能说明
      将变量表列(arg_list)中的数据,按照format指出的格式,写入由fp指定的文件。fprintf()函数与printf()函数的功能相同,只是printf()函数是将数据写入屏幕文件(stdout)。
    3.参数说明
      fp:这是个文件指针,指出要将数据写入的文件。
      format:这是个指向字符串的字符指针,字符串中含有要写出数据的格式,所以该字符串成为格式串。格式串描述的规则与printf()函数中的格式串相同。
    arg_list:是要写入文件的变量表列,各变量之间用逗号分隔。
    4.返回值
      无。
    5. 实例

    【8.5】下列程序的执行文件为display.exe,执行时键入命令行:
       display [-i][-s] filename
    下面的表格列出了命令行参数的含义及其功能:

    //存储文件名:save.txt
    //程序代码如下:
    // file display program.
    #include <stdio.h>
    void main()
    {
        char name[10];
        int nAge,nClass;
        long number;
        FILE *fp;
        if((fp=fopen("student.txt","w"))==NULL)
        {
            printf("The file %s can not be opened.\n","student.txt");
            return;
        }
        fscanf(stdin,"%s %d %d %ld",name,&nClass,&nAge,&number);
        fprintf(fp,"%s %5d %4d %8ld",name,nClass,nAge,number);
        fclose(fp);
        if((fp=fopen("student.txt","r"))==NULL)
        {
            printf("The file %s can not be opened.\n","student.txt");
            return;
        }
        fscanf(fp,"%s %d %d %ld",name,&nClass,&nAge,&number);
        printf("name nClass nAge number\n");
        fprintf(stdout,"%-10s%-8d%-6d%-8ld\n",name,nClass,nAge,number);
        fclose(fp);
    }


    G. 以二进制形式读取文件中的数据

    1. 函数原型

    int fread(void *buffer,unsigned sife,unsigned count,FILE *fp)

    2. 功能说明
      从由fp指定的文件中,按二进制形式将sife*count个数据读到由buffer指出的数据区中。
    3. 参数说明
    buffer:这是一个void型指针,指出要将读入数据存放在其中的存储区首地址。
    sife:指出一个数据块的字节数,即一个数据块的大小尺寸。
    count:指出一次读入多少个数据块(sife)。
    fp:这是个文件指针,指出要从其中读出数据的文件。
    4.返回值
      正常返回:实际读取数据块的个数,即count。
      异常返回:如果文件中剩下的数据块个数少于参数中count指出的个数,或者发生了错误,返回0值。此时可以用feof()和ferror()来判定到底出现了什么
    情况。

    H. 以二进制形式写数据到文件中去

    1. 函数原型

    int fwrite(void *buffer,unsigned sife,unsigned count,FILE *fp)

    2. 功能说明
      按二进制形式,将由buffer指定的数据缓冲区内的sife*count个数据写入由fp指定的文件中去。
    3. 参数说明
    buffer:这是一个void型指针,指出要将其中数据输出到文件的缓冲区首地址。
    sife:指出一个数据块的字节数,即一个数据块的大小尺寸。
    count:一次输出多少个数据块(sife)。
    fp:这是个文件指针,指出要从其中读出数据的文件。
    4.返回值
      正常返回:实际输出数据块的个数,即count。
      异常返回:返回0值,表示输出结束或发生了错误。
    5.实例

    【例8.7】

    #include <stdio.h>
    #define SIZE 4
    struct worker
    { int number;
        char name[20];
        int age;
    };
    void main()
    {
        struct worker wk;
        int n;
        FILE *in,*out;
        if((in=fopen("file1.txt","rb"))==NULL)
        {
            printf("The file %s can not be opened.\n","file1.txt");
            return;
        }
        if((out=fopen("file2.txt","wb"))==NULL)
        {
            printf("The file %s can not be opened.\n","file2.txt");
            return;
        }
        while(fread(&wk,sizeof(struct worker),1,in)==1)
            fwrite(&wk,sizeof(struct worker),1,out);
        fclose(in);
        fclose(out);
    }


    I. 以二进制形式读取一个整数

    1. 函数原型

    int getw(FILE *fp)

    2. 功能说明
      从由fp指定的文件中,以二进制形式读取一个整数。
    3. 参数说明
      fp:是文件指针。
    4. 返回值
      正常返回:所读取整数的值。
      异常返回:返回EOF,即-1。由于读取的整数值有可能是-1,所以必须用feof()或ferror()来判断是到了文件结束,还是出现了一个出错。
    5. 实例

    【例8.8】

    #include <stdio.h>
    void main(int argc,char *argv[])
    {
        int i,sum=0;
        FILE *fp;
        if(argc!=2)
        {
            printf("Command error,Usage: readfile filename\n");
            exit(1);
        }
        if(!(fp=fopen(argv[1],"rb")))
        {
            printf("The file %s can not be opened.\n",argv[1]);
            exit(1);
        }
        for(i=1;i<=10;i++) sum+=getw(fp);
        printf("The sum is %d\n",sum);
        fclose(fp);
    }


    J. 以二进制形式存贮一个整数

    1.函数原型

    int putw(int n,FILE *fp)

    2. 功能说明
     以二进制形式把由变量n指出的整数值存放到由fp指定的文件中。
    3. 参数说明
     n:要存入文件的整数。
     fp:是文件指针。
    4. 返回值
     正常返回:所输出的整数值。
     异常返回:返回EOF,即-1。由于输出的整数值有可能是-1,所以必须用feof()或ferror()来判断是到了文件结束,还是出现了一个出错。
    5. 实例

    【例8.9】

    #include <stdio.h>
    void main(int argc,char *argv[])
    {
        int i;
        FILE *fp;
        if(argc!=2)
        {
            printf("Command error,Usage: writefile filename\n");
            return;
        }
    
        if(!(fp=fopen(argv[1],"wb")))
        {
            printf("The file %s can not be opened.\n",argv[1]);
            return;
        }
        for(i=1;i<=10;i++) printf("%d\n", putw(i,fp));
        fclose(fp);
    }


    * 文件状态检查

    A. 文件结束
    (1) 函数原型

    int feof(FILE *fp)

    (2) 功能说明
       该函数用来判断文件是否结束。
    (3) 参数说明
       fp:文件指针。
    (4) 返回值
       0:假值,表示文件未结束。
       1:真值,表示文件结束。
    (5) 实例

    【例8.10】

    #include <stdio.h>
    void main(int argc,char *argv[])
    {
        FILE *in,*out;
        char ch;
        if(argc!=3)
        {
            printf("Usage: copyfile filename1 filename2\n");
            return;
        }
        if((in=fopen(argv[1],"rb"))==NULL)
        {
            printf("The file %s can not be opened.\n",argv[1]);
            return;
        }
        if((out=fopen(argv[2],"wb"))==NULL)
        {
            printf("The file %s can not be opened.\n",argv[2]);
            return;
        }
        while(!feof(in))
        {
            ch=fgetc(in);
            if(ferror(in))
            {
                printf("read error!\n");
                clearerr(in);
            }
            else
            {
                fputc(ch,out);
                if(ferror(out))
                {
                    printf("write error!\n");
                    clearerr(out);
                }
            }
        }
        fclose(in);
        fclose(out);
    }


    B. 文件读/写出错
    (1) 函数原型

    int ferror(FILE *fp)

    (2) 功能说明
       检查由fp指定的文件在读写时是否出错。
    (3) 参数说明
       fp:文件指针。
    (4) 返回值
       0:假值,表示无错误。
       1:真值,表示出错。

    C. 清除文件错误标志

    (1) 函数原型

    void clearerr(FILE *fp)

    (2) 功能说明
       清除由fp指定文件的错误标志。
    (3) 参数说明
       fp:文件指针。
    (4) 返回值
       无。
    (5) 实例

    【例8.12】

    #include <stdio.h>
    void main(int argc,char *argv[])
    {
        FILE *in,*out;
        char ch;
        if(argc!=3)
        {
            printf("Usage: copyfile filename1 filename2\n");
            return;
        }
        if((in=fopen(argv[1],"rb"))==NULL)
        {
            printf("The file %s can not be opened.\n",argv[1]);
            return;
        }
        if((out=fopen(argv[2],"wb"))==NULL)
        {
            printf("The file %s can not be opened.\n",argv[2]);
            return;
        }
        while(!feof(in))
        {
            ch=fgetc(in);
            if(ferror(in))
            {
                printf("read error!\n");
                clearerr(in);
            }
            else
            {
                fputc(ch,out);
                if(ferror(out))
                {
                    printf("write error!\n");
                    clearerr(out);
                }
            }
        }
        fclose(in);
        fclose(out);
    }


    D. 了解文件指针的当前位置
    (1) 函数原型

    long ftell(FILE *fp)

    (2) 功能说明
       取得由fp指定文件的当前读/写位置,该位置值用相对于文件开头的位移量来表示。
    (3) 参数说明
       fp:文件指针。
    (4) 返回值
       正常返回:位移量(这是个长整数)。
       异常返回:-1,表示出错。
    (5) 实例

    * 文件定位

    A. 反绕
    (1) 函数原型

    void rewind(FILE *fp)

    (2) 功能说明
       使由文件指针fp指定的文件的位置指针重新指向文件的开头位置。
    (3) 参数说明
       fp:文件指针。
    (4) 返回值
       无。
    (5) 实例

    【例8.14】

    #include <stdio.h>
    void main()
    {
        FILE *in,*out;
        in=fopen("filename1","r");
        out=fopen("filename2","w");
        while(!feof(in)) fputc(fgetc(in),out);
        rewind(out);
        while(!feof(in)) putchar(fgetc(in));
        fclose(in);
        fclose(out);
    }

    B. 随机定位
    (1) 函数原型

    int fseek(FILE *fp,long offset,int base)

    (2) 功能说明
       使文件指针fp移到基于base的相对位置offset处。
    (3)参数说明
       fp:文件指针。
       offset:相对base的字节位移量。这是个长整数,用以支持大于64KB的文件。
       base:文件位置指针移动的基准位置,是计算文件位置指针位移的基点。ANSI C定义了base的可能取值,以及这些取值的符号常量。

    (4)返回值

      正常返回:当前指针位置。
      异常返回:-1,表示定位操作出错。

    (5)实例
    【例8.15】

    #include <stdio.h>
    #include <string.h>
    struct std_type
    {
        int num;
        char name[20];
        int age;
        char class;
    }stud;
    int cstufile()
    {
        int i;
        FILE *fp;
        if((fp=fopen("stufile","wb"))==NULL)
        {
            printf("The file can't be opened for write.\n");
            return 0;
        }
        for(i=1;i<=100;i++)
        {
            stud.num=i;
            strcpy(stud.name,"aaaa");
            stud.age=17;
            stud.class='8';
            fwrite(&stud,sizeof(struct std_type),1,fp);
        }
        fclose(fp);
        return 1;
    }
    void main()
    {
        int n;
        FILE *fp;
        if(cstufile()==0) return;
        if((fp=fopen("stufile","rb"))==NULL)
        {
            printf("The file can not be opened.\n");
            return;
        }
        for(n=0;n<100;n+=2)
        {
            fseek(fp,n*sizeof(struct std_type),SEEK_SET);
            fread(&stud,sizeof(struct std_type),1,fp);
            printf("%10d%20s%10d%4c\n",stud.num,stud.name,stud.age,stud.class);
        }
        fclose(fp);
    }


    * 关于exit()函数
    1. 函数原型

    void exit(int status)

    2. 功能说明
      exit()函数使程序立即终止执行,同时将缓冲区中剩余的数据输出并关闭所有已经打开的文件。
    3. 参数说明
      status:为0值表示程序正常终止,为非0值表示一个定义错误。
    4. 返回值
      无。

    * 关于feof()函数
    1. 函数原型

    int feof(FILE *fp)

    2. 功能说明
       在文本文件(ASCII文件)中可以用值为-1的符号常量EOF来作为文件的结束符。但是在二进制文件中-1往往可能是一个有意义的数据,因此不能用它 来作为文件的结束标志。为了能有效判别文件是否结束,ANSI C提供了标准函数feof(),用来识别文件是否结束。
    3. 参数说明
      fp:文件指针。
    4. 返回值
      返回为非0值:已到文件尾。
      返回为0值:表示还未到文件尾。

    展开全文
  • c++文件操作大全

    万次阅读 多人点赞 2020-10-28 08:28:51
    c++文件操作大全 基于C的文件操作  在ANSI C中,对文件的操作分为两种方式,即流式文件操作和I/O文件操作,下面就分别介绍之。 一、流式文件操作 这种方式的文件操作有一个重要的结构FILE,FILE在stdio.h中定义...

    c++文件操作大全

    基于C的文件操作 
      在ANSI C中,对文件的操作分为两种方式,即流式文件操作和I/O文件操作,下面就分别介绍之。

    一、流式文件操作 
    这种方式的文件操作有一个重要的结构FILE,FILE在stdio.h中定义如下:

    复制代码

    typedef struct { 
      int level;           /* fill/empty level of buffer */ 
      unsigned flags;        /* File status flags */ 
      char fd;            /* File descriptor */ 
      unsigned char hold;      /* Ungetc char if no buffer */ 
      int bsize;           /* Buffer size */ 
      unsigned char _FAR *buffer; /* Data transfer buffer */ 
      unsigned char _FAR *curp;  /* Current active pointer */ 
      unsigned istemp;      /* Temporary file indicator */ 
      short token;          /* Used for validity checking */ 
    } FILE;              /* This is the FILE object */ 

    复制代码

      FILE这个结构包含了文件操作的基本属性,对文件的操作都要通过这个结构的指针来进行,此种文件操作常用的函数见下表 函数 功能 

      fopen() 打开流 
      fclose() 关闭流 
      fputc() 写一个字符到流中 
      fgetc() 从流中读一个字符 
      fseek() 在流中定位到指定的字符 
      fputs() 写字符串到流 
      fgets() 从流中读一行或指定个字符 
      fprintf() 按格式输出到流 
      fscanf() 从流中按格式读取 
      feof() 到达文件尾时返回真值 
      ferror() 发生错误时返回其值 
      rewind() 复位文件定位器到文件开始处 
      remove() 删除文件 
      fread() 从流中读指定个数的字符 
      fwrite() 向流中写指定个数的字符 
      tmpfile() 生成一个临时文件流 
      tmpnam() 生成一个唯一的文件名


    下面就介绍一下这些函数

    1.fopen() 
      fopen的原型是:FILE *fopen(const char *filename,const char *mode),fopen实现三个功能

      为使用而打开一个流 
      把一个文件和此流相连接 
      给此流返回一个FILR指针 
      参数filename指向要打开的文件名,mode表示打开状态的字符串,其取值如下表

      字符串 含义 
      "r" 以只读方式打开文件 
      "w" 以只写方式打开文件 
      "a" 以追加方式打开文件 
      "r+" 以读/写方式打开文件,如无文件出错 
      "w+" 以读/写方式打开文件,如无文件生成新文件

      一个文件可以以文本模式或二进制模式打开,这两种的区别是:在文本模式中回车被当成一个字符'/n',而二进制模式认为它是两个字符0x0D,0x0A;如果在文件中读到0x1B,文本模式会认为这是文件结束符,也就是二进制模型不会对文件进行处理,而文本方式会按一定的方式对数据作相应的转换。

      系统默认的是以文本模式打开,可以修改全部变量_fmode的值来修改这个设置,例如_fmode=O_TEXT;就设置默认打开方式为文本模式;而_fmode=O_BINARY;则设置默认打开方式是二进制模式。

      我们也可以在模式字符串中指定打开的模式,如"rb"表示以二进制模式打开只读文件,"w+t"或"wt+"表示以文本模式打开读/写文件。

      此函数返回一个FILE指针,所以申明一个FILE指针后不用初始化,而是用fopen()来返回一个指针并与一个特定的文件相连,如果成败,返回NULL。

      例:

      FILE *fp; 
      if(fp=fopen("123.456","wb")) 
      puts("打开文件成功"); 
      else 
      puts("打开文件成败");

    2.fclose() 
      fclose()的功能就是关闭用fopen()打开的文件,其原型是:int fclose(FILE *fp);如果成功,返回0,失败返回EOF。

      在程序结束时一定要记得关闭打开的文件,不然可能会造成数据丢失的情况,我以前就经常犯这样的毛病。

      例:fclose(fp);

    3.fputc() 
      向流写一个字符,原型是int fputc(int c, FILE *stream); 成功返回这个字符,失败返回EOF。

      例:fputc('X',fp);

    4.fgetc() 
      从流中读一个字符,原型是int fputc(FILE *stream); 成功返回这个字符,失败返回EOF。

      例:char ch1=fgetc(fp);

    5. fseek() 
      此函数一般用于二进制模式打开的文件中,功能是定位到流中指定的位置,原型是int fseek(FILE *stream, long offset, int whence);如果成功返回0,参数offset是移动的字符数,whence是移动的基准,取值是

      符号常量 值 基准位置 
      SEEK_SET 0 文件开头 
      SEEK_CUR 1 当前读写的位置 
      SEEK_END 2 文件尾部

      例:fseek(fp,1234L,SEEK_CUR);//把读写位置从当前位置向后移动1234字节(L后缀表示长整数)

      fseek(fp,0L,2);//把读写位置移动到文件尾

    6.fputs() 
      写一个字符串到流中,原型int fputs(const char *s, FILE *stream);

      例:fputs("I Love You",fp);

    7.fgets() 
      从流中读一行或指定个字符,原型是char *fgets(char *s, int n, FILE *stream); 从流中读取n-1个字符,除非读完一行,参数s是来接收字符串,如果成功则返回s的指针,否则返回NULL。

      例:如果一个文件的当前位置的文本如下

      Love ,I Have

      But ........

      如果用

      fgets(str1,4,file1);

      则执行后str1="Lov",读取了4-1=3个字符,而如果用

      fgets(str1,23,file1);

      则执行str="Love ,I Have",读取了一行(不包括行尾的'/n')。

    8.fprintf() 
      按格式输入到流,其原型是int fprintf(FILE *stream, const char *format[, argument, ...]);其用法和printf()相同,不过不是写到控制台,而是写到流罢了

      例:fprintf(fp,"%2d%s",4,"Hahaha");

    9.fscanf() 
      从流中按格式读取,其原型是int fscanf(FILE *stream, const char *format[, address, ...]);其用法和scanf()相同,不过不是从控制台读取,而是从流读取罢了。

      例:fscanf(fp,"%d%d" ,&x,&y);

    10.feof() 
      检测是否已到文件尾,是返回真,否则返回0,其原型是int feof(FILE *stream);

      例:if(feof(fp))printf("已到文件尾");

    11.ferror() 
      原型是int ferror(FILE *stream);返回流最近的错误代码,可用clearerr()来清除它,clearerr()的原型是void clearerr(FILE *stream);

      例:printf("%d",ferror(fp));

    12.rewind() 
      把当前的读写位置回到文件开始,原型是void rewind(FILE *stream);其实本函数相当于fseek(fp,0L,SEEK_SET);

      例:rewind(fp);

    13.remove() 
      删除文件,原型是int remove(const char *filename); 参数就是要删除的文件名,成功返回0。

      例:remove("c://io.sys");

    14.fread() 
      从流中读指定个数的字符,原型是size_t fread(void *ptr, size_t size, size_t n, FILE *stream);参数ptr是保存读取的数据,void*的指针可用任何类型的指针来替换,如char*、int *等等来替换;size是每块的字节数;n是读取的块数,如果成功,返回实际读取的块数(不是字节数),本函数一般用于二进制模式打开的文件中。

      例:

      char x[4230]; 
      FILE *file1=fopen("c://msdos.sys","r"); 
      fread(x,200,12 ,file1);//共读取200*12=2400个字节

    15.fwrite() 
      与fread对应,向流中写指定的数据,原型是size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream);参数ptr是要写入的数据指针,void*的指针可用任何类型的指针来替换,如char*、int *等等来替换;size是每块的字节数;n是要写的块数,如果成功,返回实际写入的块数(不是字节数),本函数一般用于二进制模式打开的文件中。

      例:

      char x[]="I Love You"; 
      fwire(x, 6,12,fp);//写入6*12=72字节

      将把"I Love"写到流fp中12次,共72字节

    16.tmpfile() 
      其原型是FILE *tmpfile(void); 生成一个临时文件,以"w+b"的模式打开,并返回这个临时流的指针,如果失败返回NULL。在程序结束时,这个文件会被自动删除。

      例:FILE *fp=tmpfile();

    17.tmpnam(); 
      其原型为char *tmpnam(char *s); 生成一个唯一的文件名,其实tmpfile()就调用了此函数,参数s用来保存得到的文件名,并返回这个指针,如果失败,返回NULL。

     

    borland c++ bulder的文件操作总结2

    二、直接I/O文件操作 
      这是C提供的另一种文件操作,它是通过直接存/取文件来完成对文件的处理,而上篇所说流式文件操作是通过缓冲区来进行;流式文件操作是围绕一个FILE指针来进行,而此类文件操作是围绕一个文件的"句柄"来进行,什么是句柄呢?它是一个整数,是系统用来标识一个文件(在WINDOWS中,句柄的概念扩展到所有设备资源的标识)的唯一的记号。此类文件操作常用的函数如下表,这些函数及其所用的一些符号在io.h和fcntl.h中定义,在使用时要加入相应的头文件。

      函数 说明 
      open() 打开一个文件并返回它的句柄 
      close() 关闭一个句柄 
      lseek() 定位到文件的指定位置 
      read() 块读文件 
      write() 块写文件 
      eof() 测试文件是否结束 
      filelength() 取得文件长度 
      rename() 重命名文件 
      chsize() 改变文件长度

    下面就对这些函数一一说明:

    1.open() 
      打开一个文件并返回它的句柄,如果失败,将返回一个小于0的值,原型是int open(const char *path, int access [, unsigned mode]); 参数path是要打开的文件名,access是打开的模式,mode是可选项。表示文件的属性,主要用于UNIX系统中,在DOS/WINDOWS这个参数没有意义。其中文件的打开模式如下表。

      符号 含义 符号 含义 符号 含义 
      O_RDONLY 只读方式 O_WRONLY 只写方式 O_RDWR 读/写方式 
      O_NDELAY 用于UNIX系统 O_APPEND 追加方式 O_CREAT 如果文件不存在就创建 
      O_TRUNC 把文件长度截为0 O_EXCL 和O_CREAT连用,如果文件存在返回错误 O_BINARY 二进制方式 
      O_TEXT 文本方式

      对于多个要求,可以用"|"运算符来连接,如O_APPEND|O_TEXT表示以文本模式和追加方式打开文件。

      例:int handle=open("c://msdos.sys",O_BINARY|O_CREAT|O_WRITE)

    2.close() 
      关闭一个句柄,原型是int close(int handle);如果成功返回0

      例:close(handle)

    3.lseek() 
      定位到指定的位置,原型是:long lseek(int handle, long offset, int fromwhere);参数offset是移动的量,fromwhere是移动的基准位置,取值和前面讲的fseek()一样,SEEK_SET:文件首部;SEEK_CUR:文件当前位置;SEEK_END:文件尾。此函数返回执行后文件新的存取位置。

      例:

      lseek(handle,-1234L,SEEK_CUR);//把存取位置从当前位置向前移动1234个字节。 
      x=lseek(hnd1,0L,SEEK_END);//把存取位置移动到文件尾,x=文件尾的位置即文件长度

    4.read() 
      从文件读取一块,原型是int read(int handle, void *buf, unsigned len);参数buf保存读出的数据,len是读取的字节。函数返回实际读出的字节。

      例:char x[200];read(hnd1,x,200);

    5.write() 
      写一块数据到文件中,原型是int write(int handle, void *buf, unsigned len);参数的含义同read(),返回实际写入的字节。

      例:char x[]="I Love You";write(handle,x,strlen(x));

    6.eof() 
      类似feof(),测试文件是否结束,是返回1,否则返回0;原型是:int eof(int handle);

      例:while(!eof(handle1)){……};

    7.filelength() 
      返回文件长度,原型是long filelength(int handle);相当于lseek(handle,0L,SEEK_END)

      例:long x=filelength(handle);

    8.rename() 
      重命名文件,原型是int rename(const char *oldname, const char *newname); 参数oldname是旧文件名,newname是新文件名。成功返回0

      例:rename("c://config.sys","c://config.w40");

    9.chsize(); 
      改变文件长度,原型是int chsize(int handle, long size);参数size表示文件新的长度,成功返回0,否则返回-1,如果指定的长度小于文件长度,则文件被截短;如果指定的长度大于文件长度,则在文件后面补'/0'。

      例:chsize(handle,0x12345);


    --------------------------------------------------------------------------------

      如果熟悉汇编可能会发现这种方式和汇编语言的DOS功能调用句柄式文件操作很像,比如open()就像DOS服务的3CH号功能调用,其实这种操作还有两种类型的函数就是直接用DOS功能来完成的,如_open(),_dos_open()等等。有兴趣可自已查询BCB的帮助。

      同流式文件操作相同,这种也提供了Unicode字符操作的函数,如_wopen()等等,用于9X/NT下的宽字符编程,有兴趣可自已查询BCB的帮助。

      另外,此种操作还有lock(),unlock(),locking()等用于多用户操作的函数,但在BCB中用得并不多,我就不介绍了,但如果要用C来写CGI,这些就必要的常识了,如果你有这方面的要求,那就得自已好好看帮助了。

      到这里,我就把基于C的文件操作介绍完了,下一篇将介绍基于C++的文件操作,敬请期待。

    在C++中,有一个stream这个类,所有的I/O都以这个"流"类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符:

    1、插入器(<<) 
      向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,所以,cout<<"Write Stdout"<<'/n';就表示把字符串"Write Stdout"和换行字符('/n')输出到标准输出流。

    2、析取器(>>) 
      从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘,所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。

    在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。

    一、打开文件 
      在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是:

      void open(const char* filename,int mode,int access);

      参数:

      filename:  要打开的文件名 
      mode:    要打开文件的方式 
      access:   打开文件的属性 
      打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:

      ios::app:   以追加的方式打开文件 
      ios::ate:   文件打开后定位到文件尾,ios:app就包含有此属性 
      ios::binary:  以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文 
      ios::in:    文件以输入方式打开 
      ios::out:   文件以输出方式打开 
      ios::nocreate: 不建立文件,所以文件不存在时打开失败  
      ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败 
      ios::trunc:  如果文件存在,把文件长度设为0 
      可以用"或"把以上属性连接起来,如ios::out|ios::binary

      打开文件的属性取值是:

      0:普通文件,打开访问 
      1:只读文件 
      2:隐含文件 
      4:系统文件 
      可以用"或"或者"+"把以上属性连接起来 ,如3或1|2就是以只读和隐含属性打开文件。

      例如:以二进制输入方式打开文件c:/config.sys

      fstream file1; 
      file1.open("c://config.sys",ios::binary|ios::in,0);

      如果open函数只有文件名一个参数,则是以读/写普通文件打开,即:

      file1.open("c://config.sys");<=>file1.open("c://config.sys",ios::in|ios::out,0);

      另外,fstream还有和open()一样的构造函数,对于上例,在定义的时侯就可以打开文件了:

      fstream file1("c://config.sys");

      特别提出的是,fstream有两个子类:ifstream(input file stream)和ofstream(outpu file stream),ifstream默认以输入方式打开文件,而ofstream默认以输出方式打开文件。

      ifstream file2("c://pdos.def");//以输入方式打开文件 
      ofstream file3("c://x.123");//以输出方式打开文件

      所以,在实际应用中,根据需要的不同,选择不同的类来定义:如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定义。


    二、关闭文件 
      打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:file1.close();就把file1相连的文件关闭。

    三、读写文件 
      读写文件分为文本文件和二进制文件的读取,对于文本文件的读取比较简单,用插入器和析取器就可以了;而对于二进制的读取就要复杂些,下要就详细的介绍这两种方式

      1、文本文件的读写 
      文本文件的读写很简单:用插入器(<<)向文件输出;用析取器(>>)从文件输入。假设file1是以输入方式打开,file2以输出打开。示例如下:

      file2<<"I Love You";//向文件写入字符串"I Love You" 
      int i; 
      file1>>i;//从文件输入一个整数值。

      这种方式还有一种简单的格式化能力,比如可以指定输出为16进制等等,具体的格式有以下一些

      操纵符 功能 输入/输出 
      dec 格式化为十进制数值数据 输入和输出 
      endl 输出一个换行符并刷新此流 输出 
      ends 输出一个空字符 输出 
      hex 格式化为十六进制数值数据 输入和输出 
      oct 格式化为八进制数值数据 输入和输出 
      setpxecision(int p) 设置浮点数的精度位数 输出

      比如要把123当作十六进制输出:file1<
      2、二进制文件的读写 
      ①put() 
      put()函数向流写入一个字符,其原型是ofstream &put(char ch),使用也比较简单,如file1.put('c');就是向流写一个字符'c'。

      ②get() 
      get()函数比较灵活,有3种常用的重载形式:

      一种就是和put()对应的形式:ifstream &get(char &ch);功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示从文件中读取一个字符,并把读取的字符保存在x中。

      另一种重载形式的原型是: int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,如x=file2.get();和上例功能是一样的。

      还有一种形式的原型是:ifstream &get(char *buf,int num,char delim='/n');这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符,如果没使用 delim 这个参数,将使用缺省值换行符'/n'。例如:

      file2.get(str1,127,'A');//从文件中读取字符到字符串str1,当遇到字符'A'或读取了127个字符时终止。

      ③读写数据块 
      要读写二进制数据块,使用成员函数read()和write()成员函数,它们原型如下:

      read(unsigned char *buf,int num); 
      write(const unsigned char *buf,int num);

      read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 int gcount();来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是 unsigned char *,有时可能需要类型转换。

      例:

      unsigned char str1[]="I Love You"; 
      int n[5]; 
      ifstream in("xxx.xxx"); 
      ofstream out("yyy.yyy"); 
      out.write(str1,strlen(str1));//把字符串str1全部写到yyy.yyy中 
      in.read((unsigned char*)n,sizeof(n));//从xxx.xxx中读取指定个整数,注意类型转换 
      in.close();out.close();

    四、检测EOF 
      成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof();

      例:  if(in.eof())ShowMessage("已经到达文件尾!");

    五、文件定位 
      和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,对应的成员函数是 seekg()和 seekp(),seekg()是设置读位置,seekp是设置写位置。它们最通用的形式如下:

      istream &seekg(streamoff offset,seek_dir origin); 
      ostream &seekp(streamoff offset,seek_dir origin);

      streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置,是一个有以下值的枚举:

      ios::beg:  文件开头 
      ios::cur:  文件当前位置 
      ios::end:  文件结尾 
      这两个函数一般用于二进制文件,因为文本文件会因为系统对字符的解释而可能与预想的值不同。

      例:

      file1.seekg(1234,ios::cur);//把文件的读指针从当前位置向后移1234个字节 
      file2.seekp(1234,ios::beg);//把文件的写指针从文件开头向后移1234个字节

     

    ------------------------------------------------------------------------------------------------------------------------------------------

    在BCB中也提供了文件操作的函数,这些函数的功能和前面所介绍的大致相同,但这类函数和BCB关系紧密,能使用BCB中的AnsiString等数据类型,在BCB中用这种方式的文件操作是最方便的,下面我就把这种文件操作详细介绍。

    在BCB提供的这组文件操作函数中,可分为三种类型,就是:1、文件名函数,2、文件管理函数;3、文件I/O函数。

    1、文件名函数 
      文件名函数可以对文件的名称、所在子目录、驱动器和扩展名等进行操作。下表列出这些函数及其功能。

      函数 说明 
      ExpandFileName() 返回文件的全路径(含驱动器、路径) 
      ExtractFileExt() 从文件名中抽取扩展名 
      ExtractFileName() 从文件名中抽取不含路径的文件名 
      ExtractFilePath() 从文件名中抽取路径名 
      ExtractFileDir() 从文件名中抽取目录名 
      ExtractFileDrive() 从文件名中抽取驱动器名 
      ChangeFileExt() 改变文件的扩展名 
      ExpandUNCFileName() 返回含有网络驱动器的文件全路径 
      ExtractRelativePath() 从文件名中抽取相对路径信息 
      ExtractShortPathName() 把文件名转化为DOS的8·3格式 
      MatchesMask() 检查文件是否与指定的文件名格式匹配

      下面就把这些函数作一一介绍:

      ⑴ExpandFileName() 
      原型:extern PACKAGE AnsiString __fastcall ExpandFileName(const AnsiString FileName);

      功能:返回文件的全路径(含驱动器、路径)

      参数:FileName:要处理的文件名

      例:ShowMessage(ExpandFileName(Application->ExeName));//显示你的程序文件名,如C:/MyBCB/Sample1.EXE

      ⑵ExtractFileExt() 
      原型:extern PACKAGE AnsiString __fastcall ExtractFileExt(const AnsiString FileName);

      功能:从文件名中抽取扩展名

      参数:FileName:要处理的文件名(全路径)

      例:ShowMessage(ExtractFileExt(Application->ExeName));//显示".exe"

      ⑶ExtractFileName() 
      原型:extern PACKAGE AnsiString __fastcall ExtractFileName(const AnsiString FileName);

      功能:从文件名中抽取不含路径的文件名

      参数:FileName:要处理的文件名

      例:ShowMessage(ExtractFileExt("c://Winnt//SOL.EXE"));//显示"SOL.EXE"

      ⑷ExtractFilePath() 
      原型:extern PACKAGE AnsiString __fastcall ExtractFilePath(const AnsiString FileName);

      功能:从文件名中抽取路径名

      参数:FileName:要处理的文件名

      例:ShowMessage(ExtractFilePath("Winnt//SOL.EXE"));//显示"Winnt/"

      ⑸ExtractFileDir() 
      原型:extern PACKAGE AnsiString __fastcall ExtractFileDir(const AnsiString FileName);

      功能:从文件名中抽取目录名(和上个函数不同,不包括最后的"/")

      参数:FileName:要处理的文件名

      例:ShowMessage(ExtractFileDir("Winnt//SOL.EXE"));//显示"Winnt",注意和上个函数的区别

      ⑹ExtractFileDrive() 
      原型:extern PACKAGE AnsiString __fastcall ExtractFileDrive(const AnsiString FileName);

      功能:从文件名中抽取驱动器名

      参数:FileName:要处理的文件名

      例:ShowMessage(ExtractFileDrive("c://Winnt//SOL.EXE"));//显示"c:"

      ⑺ChangeFileExt() 
      原型:extern PACKAGE System::AnsiString __fastcall ChangeFileExt(const System::AnsiString FileName, const System::AnsiString Extension);

      功能:更改文件名的扩展名,不是对真正的文件进行改名,只是对文件名这个字符串进行处理

      参数:FileName:要改名的文件名,Extension:新的扩展名

      例:ShowMessage(ChangeFileExt("c://Winnt//SOL.EXE",".OOO"));//显示"c:/winnt/SOL.OOO"

      ⑻ExpandUNCFileName() 
      原型:extern PACKAGE AnsiString __fastcall ExpandUNCFileName(const AnsiString FileName);

      功能:返回含有网络驱动器的文件全路径,格式为://机器名/共享名/文件名

      参数:FileName:要处理的文件名

      例:ShowMessage(ExpandUNCFileName("F://Winnt//SOL.EXE"));/*如果F:是映射的网络驱动器//NT40/WINNT,则显示"//NT40/WINNT/SOL.EXE"*/

      ⑼ExtractRelativePath() 
      原型:extern PACKAGE AnsiString __fastcall ExtractRelativePath(const AnsiString BaseName, const AnsiString DestName);

      功能:从文件名中抽取相对路径信息,如"../sss/ss.asd"这种形式

      参数:BaseName:基准文件名;DestName:目标文件名

      例:ShowMessage(ExtractRelativePath("D://Source//c//1.123","D://Source//Asm//dz.asm"));/*显示"../asm/dz.asm"*/

      (10) ExtractShortPathName() 
      原型:extern PACKAGE AnsiString __fastcall ExtractShortPathName(const AnsiString FileName);

      功能:把文件名转换为DOS的8、3格式

      参数:FileName:要处理的文件名

      例:ShowMessage(ExtractShortPathName("E://Program Files//Dual Wheel Mouse//4dmain.exe"));/*显示"E:/Progra~1/dualwh~1/4dmain.exe"*/

      ⑾MatchesMask() 
      原型:extern PACKAGE bool __fastcall MatchesMask(const AnsiString Filename, const AnsiString Mask);

      功能:检查文件是否与指定的文件名格式匹配

      参数:FileName:要处理的文件名;Mask:文件名格式,支持通配符

      例:ShowMessage(MatchesMask("Lxf.exe","*.?x?));//显示"true"

    2、文件管理函数 
      这类函数包括设置和读取驱动器、子目录和文件的有关的各种操作,下表列出这类操作常用的函数及其功能。

      函数 功能 
      CreateDir() 创建新的子目录 
      DeleteFile() 删除文件 
      DirectoryExists() 判断目录是否存在 
      DiskFree() 获取磁盘剩余空间 
      DiskSize() 获取磁盘容量 
      FileExists() 判断文件是否存在 
      FileGetAttr() 获取文件属性 
      FileGetDate() 获取文件日期 
      GetCurrentDir() 获取当前目录 
      RemoveDir() 删除目录 
      SetCurrentDir() 设置当前目录

      下面就把这些函数作一一介绍:

      ⑴CreateDir() 
      原型:extern PACKAGE bool __fastcall CreateDir(const System::AnsiString Dir);

      功能:建立子目录,如果成功返回true,否则返回false

      参数:Dir:要建立的子目录的名字

      例:Create("ASM");//在当前目录下建立一个名为ASM的子目录

      ⑵DeleteFile() 
      原型:extern PACKAGE bool __fastcall DeleteFile(const System::AnsiString FileName);

      功能:删除文件,如果成功返回true,否则返回false

      参数:FileName:要删除的文件名

      例:if(OpenDialog1->Execute())DeleteFile(OpenDialog1->FileName);

      ⑶DirectoryExists() 
      原型:extern PACKAGE bool __fastcall DirectoryExists(const System:: AnsiString Name);

      功能:检测目录是否存在,如果存在返回true,否则返回false

      参数:Name:要检测的目录名

      例:if(!DirectoryExists("ASM"))CreateDir("ASM");//如果ASM这个目录不存在则创建之

      ⑷DiskFree() 
      原型:extern PACKAGE __int64 __fastcall DiskFree(Byte Drive);

      功能:检测磁盘剩余空间,返回值以字节为单位,如果指定的磁盘无效,返回-1

      参数:Drive:磁盘的代号,0表示当前盘, 1=A,2=B,3=C 以此类推

      例:ShowMessage(DiskFree(0));//显示当前盘的剩余空间

      ⑸DiskSize() 
      原型:extern PACKAGE __int64 __fastcall DiskSize(Byte Drive);

      功能:检测磁盘容量,返回值以字节为单位,如果指定的磁盘无效,返回-1

      参数:Drive:磁盘的代号,0表示当前盘, 1=A,2=B,3=C 以此类推

      例:ShowMessage(DiskFree(0));//显示当前盘的容量

      ⑹FileExists() 
      原型:extern PACKAGE bool __fastcall FileExists(const AnsiString FileName);

      功能:检测文件是否存在,如果存在返回true,否则返回false

      参数:FileName:要检测的文件名

      例:if(FileExists("AAA.ASM"))DeleteFile("AAA.ASM");

      ⑺FileGetAttr() 
      原型:extern PACKAGE int __fastcall FileGetAttr(const AnsiString FileName);

      功能:取得文件属性,如果出错返回-1

      返回值如下表,如果返回$00000006表示是一个具有隐含和系统属性的文件(4+2)

      常量 值 含义 
      faReadOnly $00000001 只读文件 
      faHidden $00000002 隐含文件 
      faSysFile $00000004 系统文件 
      faVolumeID $00000008 卷标 
      faDirectory $00000010 目录 
      faArchive $00000020 归档文件

      例:if(FileGetAttr("LLL.TXT")&0x2)ShowMessage("这是一个有隐含属性的文件");

      与此对应的有FileSetAttr() ,请自已查阅帮助系统


      ⑻FileGetDate() 
      原型:extern PACKAGE int __fastcall FileGetDate(int Handle);

      功能:返回文件的建立时间到1970-1-1日0时的秒数

      参数:Handle:用FileOpen()打开的文件句柄。

      例:

      int i=FileOpen("C://autoexec.bat",fmOpenRead); 
      ShowMessage(FileGetDate(i)); 
      FileClose(i);

      与此对应的有FileSetDate(),请自已查阅帮助系统

      ⑼GetCurrentDir() 
      原型:extern PACKAGE AnsiString __fastcall GetCurrentDir();

      功能:取得当前的目录名

      例:ShowMessage(GetCurrentDir());

      ⑽RemoveDir() 
      原型:extern PACKAGE bool __fastcall RemoveDir(const AnsiString Dir);

      功能:删除目录,如果成功返回true,否则返回false

      参数:Dir:要删除的目录名

      例:if(DiectoryExists("ASM"))RemoveDir("ASM");

      ⑾SetCurrentDir() 
      原型:extern PACKAGE bool __fastcall SetCurrentDir(const AnsiString Dir);

      功能:设置当前目录,如果成功返回true,否则返回false

      参数:Dir:要切换到的目录名

      例:SetCurrentDir("C://WINDOWS");


    3、文件I/O函数 
      这类函数完成对文件的读写相关的操作,这种类型的操作和C的基于I/O文件操作类似,下表列出这类操作常用的函数及其功能。


      FileOpen() 打开文件 
      FileClose() 关闭文件 
      FileRead() 读文件 
      FileSeek() 文件定位 
      FileWrite() 写文件 
      FileCreate() 创建文件

      下面就对这些函数作详细介绍。

      ⑴FileOpen() 
      原型:extern PACKAGE int __fastcall FileOpen(const AnsiString FileName, int Mode);

      功能:打开文件,如果成功返回其句柄,否则返回-1

      参数:FileName:要打开的文件名;Mode:打开的方式,取值如下表,可用"或"("|")运算符连接。

      常量 值 说明 
      ------------------------------------------------------------- 
      fmOpenRead 0 以只读属性打开 
      fmOpenWrite 1 以只写属性打开 
      fmOpenReadWrite 2 以读/写属性打开 
      fmShareCompat 0 兼容FCB方式(汇编中有相应的DOS功能调用,感兴趣自已查阅相关资料) 
      fmShareExclusive 16 共享方式:以独占方式打开,在关闭以前,别人不能访问 
      fmShareDenyWrite 32 共享方式:拒绝写访问 
      fmShareDenyRead 48 共享方式:拒绝读访问 
      fmShareDenyNone 64 共享方式:无限制,允许读写 
      例:int i=FileOpen("C://WINDOWS//Win.ini",fmOpenReadWrite|fmShareExclusive);

      ⑵FileClose() 
      原型:extern PACKAGE void __fastcall FileClose(int Handle);

      功能:关闭打开的句柄。

      参数:Handle:要关闭的句柄

      例:FileClose(i);

      ⑶FileRead() 
      原型:extern PACKAGE int __fastcall FileRead(int Handle, void *Buffer, int Count);

      功能:读文件,返回实际读取的字节数,句柄必须首先由FileOpen或FileCreate创建。

      参数:Handle:要读取的句柄;Buffer:存放读取的数据的缓冲区;Count:想读取的字节数

      例:char str[400];FileRead(hnd1,str,400);

      ⑷FileSeek() 
      原型:extern PACKAGE int __fastcall FileSeek(int Handle, int Offset, int Origin);

      功能:移动文件读取指针,成功返回文件指针的位置,失败返回-1

      参数:Handle:相关联的句柄;Offset:移动的量;Orgin:移动的基准,0=文件头,1=当前位置,2=文件尾。

      例:ShowMessage(FileSeek(hnd1,0,2));//取得文件的长度

      ⑸FileWrite() 
      原型:extern PACKAGE int __fastcall FileWrite(int Handle, const void *Buffer, int Count);

      功能:写文件,返回实际写入的字节数,句柄必须首先由FileOpen或FileCreate创建。

      参数:Handle:要写入的句柄;Buffer:存放写入数据的缓冲区;Count:想写入的字节数

      例:char str[]="I Love You";FileWrite(hnd1,str,strlen(str));

      ⑹FileCreate() 
      原型:extern PACKAGE int __fastcall FileCreate(const AnsiString FileName);

      功能:创建文件。成功返回其句柄,否则返回-1

      参数:FileName:要创建的文件名

      例:if(!FileExists("KC.C"))hnd1=FileCreate("KC.C");


    更多技巧文章、优秀资源下载:

    最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

    欢迎关注公众号:「智阅荟」,懂技术,更懂你!

    请自行搜索“智阅荟”,暂不显示二维码。

    说明:本站提供的所有软件已经过360、火绒安全检测,在使用中如有问题可在公众号留言!

    展开全文
  • 【C语言】文件(FILE)

    千次阅读 多人点赞 2019-04-05 23:19:07
    文章目录一、文件1.1 文件类型指针1.2 文件的打开与关闭1.2.1 文件的打开1.2.2 文件的关闭1.3 文件的读写1.3.1 文本文件的读写1.3.1.1 写字符函数fputc和读字符函数fgetc1.3.1. 2 写字符串函数fputs和读字符串函数...
  • 文件系统

    千次阅读 2018-09-05 09:17:21
    操作系统层:即文件系统,操作系统如何将各个硬件管理并对上提供更高层次接口; 单机引擎层:常见存储系统对应单机引擎原理大概介绍,利用文件系统接口提供更高级别的存储系统接口; 分布式层:如何将多个...
  • 文件管理

    万次阅读 2018-10-11 16:07:13
    1.下列文件物理结构中,适合随机访问且易于文件扩展的是() 连续结构 索引结构 链式结构且磁盘块定长 链式结构且磁盘块变长 解析: 文件的物理结构包括连续、链式、索引三种,其中链式结构...
  • 文件文件

    千次阅读 2019-08-08 20:16:26
    文件文件流 1. File类 Java.io.File类可以获取文件以及文件夹的一些基本的属性 常用的方法 文件名称,路径,大小,判断是否存在,删除,创建 // 创建一个文件对象(可以是文件,可以是文件夹) File file = new ...
  • FileDownload文件的下载

    千次阅读 2019-10-18 17:54:14
    文件的下载: 1)步骤: ①.设置contentType响应头:设置响应的类型是什么?通知浏览器是个下载的文件 response.setContentType("application/x-msdownload"); ②.设置Content-Disposition响应头:通知浏览器不在有...
  • 为什么80%的码农都做不了架构师?>>> ...
  • Springboot整合Mybatis,启动程序访问接口后报错:: java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure ...
  • 读取文件夹下所有的文件的文件名 DirectoryInfo[] list = new DirectoryInfo(@"D:\document").GetDirectories(); for (int i = 0; i < list.Length - 1; i++) { Console.WriteLine(list[i]); }???? 对...
  • RationalRose2007迅雷下载种子+破解文件+破解文件使用说明.rar 以前这三个是分开上传的,下载起来麻烦,还要了大家的下载积分,在这里说声抱歉!现在三个打包到一起了,也不要下载积分了! RationalRose2007迅雷...
  •  当时是大二···参加个天翼杯软件设计-_- 得了优胜奖 杯具~  用VB写个类似USB加密狗的东西···要操作文件,所以就有这篇东西了··   --------------- <br /> 最近在研究异或加密...
  • 文件属性及资源文件的使用

    千次阅读 2015-05-13 00:34:49
    一、C#文件属性1、什么是文件属性文件属性可以用来指示项目系统对应文件执行的操作。具体的操作见下文。Visual Basic和Visual C#的文件都具有4个属性:“FileName”、“BuildAcition”、“CustomTool”、”...
  • Unity文件文件引用、Meta详解

    千次阅读 2018-04-08 09:56:06
    原文链接:https://blog.uwa4d.com/archives/USparkle_inf_UnityEngine.html这是侑虎科技第381篇原创文章,感谢作者陈广忠供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们...
  • 如何打开EPUB文件

    万次阅读 2019-05-10 10:10:19
    在本文中:WindowsMaciPhone安卓将EPUB文件传输到Kindle将EPUB转换成PDF EPUB是一种电子图书标准。本文会教你如何在电脑或Kindle等移动平台打开和阅读EPUB文件。如果你觉得在某个平台打开EPUB文件太麻烦了,也可以...
  • 这个类是我用Java写一个小工具时写的,在文章里介绍得很详细了,如果耐心看完代码前近乎面向初学者的介绍内容,用起来...textRead:[类型:String] [作用:从指定目录的文件中读取的内容] textSet:[类型:String] ...
  • 从fastdfs文件系统结构中我们可以看出不管是上传文件、删除文件、修改文件及新增storager server,文件的同步都是同组 内多台storager server之间进行的; tracker server的配置文件中没有出现storage server,而...
  • 文件无法重命名文件和删除文件

    千次阅读 2009-10-05 10:03:00
    提示:访问被拒绝 请确定磁盘未满或未写保护 而且文件未被使用 问题补充:只有D盘是这样的,别的盘没事。 提问者: liwenfeng5776 最佳答案:请说明你删除不掉的文件是什么~ 这种情况很常见,但是不太好解决~一般...
1 2 3 4 5 ... 20
收藏数 10,387,774
精华内容 4,155,109
关键字:

文件