C语言的流和文件

来源:互联网 发布:javascript语法大全 编辑:程序博客网 时间:2024/05/22 06:47

流是一个连接输入源与输入缓冲区、输出缓冲区与输出目的地的管道。如果不使用缓冲区,流则直接连通输入源和输出目的地。磁盘上的文件是常用的输入源和输出目的地。

文件指针

C程序中的流是通过文件指针访问的,其类型为FILE *FILE是在stdio.h中定义的类型。虽然操作系统通常会限制在任意时刻打开的流的数量,但可以声明任意数量的FILE *类型变量。

stdio.h中提供了3个文件指针stdinstdoutstderr,分别用以访问标准输入流、标准输出流和标准错误流。标准输入流的输入源为键盘,标准输出流和标准错误流的输出目的地为屏幕。

文件指针 流 默认含义 stdin 标准输入 键盘 stdout 标准输出 屏幕 stderr 标准错误 屏幕

scanfprintfputchargetcharputsgets都是通过stdin输入,通过stdout输出的。

某些操作系统通过重定向机制改变标准流的默认含义。输入重定向将stdin访问的流的输入源由键盘改为文件,输出重定向将stdout访问的流的输出目标由屏幕更改为文件。在Linux系统中,输入重定向是使用<后接输入文件名实现的,而输出重定向是使用>后接输出文件名实现的,同时还可以将输出重定向和输入重定向合并使用,其使用格式为:

运行程序名 <输入文件名运行程序名 >输出文件名运行程序名 <输入文件名 >输出文件名

为了避免在重定向时将错误信息也输入到文件中,使用stderr输出错误信息。

/************************************* * redirect.c                        * *                                   * * 输入输出重定向                    * *************************************/#include <stdio.h>int main(){  int x = 0;  int y = 0;  printf("输入两个整数: ");  scanf("%d%d", &x, &y);  printf("x = %d, y = %d\n", x, y);  return 0;}

重定向

文本文件和二进制文件

文件的类型有两种,一种为文本文件,一种为二进制文件。文本文件中字节表示字符,而二进制文件中,字节并不一定表示字符,字节组可以表示整型、浮点型等类型数据的二进制形式。

根据实际需要,选择合适的文件类型。当需要支持在屏幕上展示文件的内容时,应使用文本文件。

文件操作

打开文件

打开访问文件的流(简称打开文件)的函数的原型为:

FILE *fopen(const char *filename, const char *mode);

第一个参数为要打开的文件名的字符串(文件名可能包括路径信息,以明确地指定文件,可以是相对路径也可以是绝对路径),第二个参数是模式字符串,说明对文件执行的操作模式。fopen返回一个指针变量,需要将其存放在一个指针变量中,至少供关闭流时使用。如果因指定的文件不存在或无权访问文件等原因而无法打开文件,fopen将返回一个空指针。注意始终要测试fopen的返回值。

fopen可以使用的模式字符串如下表所示:

字符串 含义 "r" 打开文本文件用于读 "rb" 打开二进制文件用于读 "w" 打开文件用于写,若文件不存在,创建新文件 "wb" 打开二进制文件用于写,若文件不存在,创建新文件 "a" 打开文件用于追加内容,若文件不存在,创建新文件 "ab" 打开二进制文件用于追加内容,若文件不存在,创建新文件 "r+" 打开文件用于读和写,从文件头开始 "r+b""rb+" 打开二进制文件用于读和写,从文件头开始 "w+" 打开文件用于读和写,如果文件已存在则覆盖其内容 "w+b""wb+" 打开二进制文件用于读和写,如果文件已存在则覆盖其内容 "a+" 打开文件用于读和写,以追加的方式写入 "a+b""ab+" 打开文件用于读和写,以追加的方式写入

关闭文件

关闭文件的函数的原型为:

int fclose(FILE *stream);

fclose关闭指向文件的流。该函数的参数为指向某个以打开的流的文件指针(不能是标准流,它们自动被打开,不能并关闭)。如果成功关闭了文件流,则返回0,否则返回错误代码EOF

/************************************* * open_close_a_file.c               * *                                   * * 打开关闭文件流                    * *************************************/#include <stdio.h>int main(){  FILE *fp = NULL;  fp = fopen("test.txt", "r");  if (fp == NULL)    printf("文件test.txt不存在!\n");  else    fclose(fp);  FILE *fp2 = NULL;  fp2 = fopen("test.txt", "w");  if (fp2 == NULL)  {    printf("文件test.txt不存在!\n");    return 0;  }  fclose(fp2);  return 0;}

打开和关闭文件

重定向文件

freopen函数为已打开的流指定一个不同的输入源文件或目标文件。freopen的函数原型为:

FILE *freopen(const char *filename, const char *mode, FILE *stream);

freopen常用以为标准流重定向,包括输入重定向、输出重定向或错误输出重定向。它实际上是先关闭stream原先指向的流,在使stream重新关联新打开的流。该函数的返回值是第三个实际参数,如果无法打开新的文件,则返回空指针。

/************************************* * redirect_stream.c                 * *                                   * * 利用freopen重定向流               * *************************************/#include <stdio.h>int main(){  FILE *fp = NULL;  fp = fopen("test.txt", "w");  freopen("test2.txt", "w", fp);  fprintf(fp, "现在流指向test2.txt\n");  fclose(fp);  return 0;}

重定向流

临时文件

程序中经常要使用临时文件,C语言的stdio库提供了两个函数来处理临时文件,它们分别为tmpfile函数和tmpnam函数,其原型分别为:

FILE *tmpfile(void);char *tmpnam(char *s);

tmpfile函数产生临时文件,该文件要么直接在程序运行过程中被关闭而销毁,要么在程序终止时自动销毁。tmpfile函数的返回值是一个指针变量,如果创建临时文件失败,则返回空指针。使用tmpfile的缺点是无法知道文件名,并且不能让其成为永久文件,解决这些问题的方法是用fopen来创建临时文件。

创建临时文件时需要生成临时文件名,tmpnam就提供这样的功能。如果传入tmpnam的是空指针,那么tmpnam会创建一个静态变量来保存创建的文件名,并返回该变量的指针,如果传入的是一个字符数组,则会将生成的文件名复制到该字符数组内,同时也会返回静态变量的指针。<stdio.h>中定义了宏L_tmpnam,指定了临时文件名的字符数组长度。在使用tmpnam函数时请确保出入的字符数组至少包含L_tmpnam个字符,且避免频繁地调用该函数,TMP_MAX宏定义了程序执行期间tmpnam函数产生的临时文件名的最大数量。

/************************************* * tmp_file_name.c                   * *                                   * * 利用tmpfile和tmpname生成临时文件和* * 文件名                            * *************************************/#include <stdio.h>#include <stdlib.h>int main(){  FILE *fp = NULL;  fp = tmpfile();  fprintf(fp, "Hello World");  system("ls -la");  unsigned long tmpNamLength = L_tmpnam;  printf("临时文件的字符数组长度: %lu\n", tmpNamLength);  char tmpFileName[L_tmpnam];  tmpnam(tmpFileName);  printf("生成的随机文件名为%s\n", tmpFileName);  char *tmpFileName2 = tmpnam(NULL);  printf("生成的第二个随机文件名为%s\n", tmpFileName2);  unsigned long tmpFileNum = TMP_MAX;  printf("程序执行期间产生的最多%lu个随机文件名\n", tmpFileNum);  return 0;}

编译过程中有一个警告信息,提示tmpnam函数安全性差,建议使用mkstemp函数。
临时文件

文件缓冲

缓冲是解决磁盘驱动器和内存速度不一致的有效方式。缓冲的使用机制如下:写入流的数据实际是存储在内存的缓冲区内,当缓冲区满或流关闭时,缓冲区会将被“清洗”以将数据写入实际的输出设备。输入流类似地从输入设备中获得数据并放在缓冲区中,内存直接从缓冲区读取数据。文件流的函数会自动处理缓冲操作,但C语言也提供了fflush函数、setbuf函数和setvbuf函数主动执行缓冲相关操作,它们的原型分别为:

int fflush(FILE *stream);int setbuf(FILE *stream, char *buf);int setvbuf(FILE *stream, char *buf, int node, size_t size);

通过fflush函数可以频繁地清洗缓冲区,而不需要等缓冲区满或文件关闭时才执行。当实际参数为文件指针,则清洗该文件指针访问的流的缓冲区,若实际参数为NULL,则清晰所有输出流的缓冲区。如果调用成功,则返回0,否则返回EOF

setvbuf用以改变缓冲流的方式,并且允许控制缓冲流的大小和位置。setvbuf的第二个参数指定期望缓冲区的地址,第三个参数说明了期望缓冲区的类型,包括以下几项:

  • _IOFBF (满缓冲)。当缓冲区为空时,从流中读入数据,当缓冲区满时,向流写入数据。
  • _IOLBF(行缓冲)。每次从流向缓冲区读入或从缓冲区向流写入一行数据。
  • _IONBF(无缓冲)。不使用缓冲区直接从流读入输入或直接向流写入数据。

第四个参数指定缓冲区内字节的数量,较大的缓冲区提高性能,较小的缓冲区节约空间。

setbuf是一个过期的函数,用以设定缓冲模式的默认值和大小,不建议使用。

删除和重命名文件

可以利用下列函数删除或重命名文件,执行基本的文件管理操作:

int remove(const char *filename);int rename(const char *old, const char *new);

如果函数调用成功,则返回0,否则返回非零值。确保在重命名之前关闭访问文件的流。

删除和重命名文件

参考文献

1.K.N. King 著,吕秀峰 译. C语言程序设计-现代方法. 人民邮电出版社
2. http://www.360doc.com/content/12/1114/16/3398926_247829293.shtml
3. http://www.docin.com/p-293383919.html

0 0
原创粉丝点击