C语言文件操作

磁盘文件与设备文件

  • 文件大体上可以分为两类,一类是磁盘文件,一类是设备文件。

磁盘文件

  • 磁盘文件是指通常存储在外部介质比如磁盘上的数据,通常只有在使用时才调入内存。
  • 磁盘文件又可以分为文本文件和二进制文件,虽然在物理上都是以二进制的方式存储的,但是文本文件和二进制文件的编码格式不同。

文本文件

  • 文本文件是基于字符编码的文件

二进制文件

  • 二进制文件是基于值编码的文件
  • 二进制文件通常占的空间更小,如下例子:

设备文件

  • 操作系统把每一个与主机相连的设备都看作文件,把它们的输入输出等同于对磁盘文件的读和写。

文件的打开与关闭

FILE结构体与文件指针

  • FILE结构体在头文件“stdio.h”中声明,一般不直接使用FILE结构体变量,而是设置一个指向FILE类型变量的指针,然后通过该指针来操作这些FILE结构体变量。这种指针即称为文件指针
  • FILE结构体定义如下,其中包含文件名、文件状态和文件当前位置等信息。
  • 需要注意的是,在整个文件操作中,我们都不会改变文件指针FILE *P的值,比如在读取一个文件的内容时,我们是FILE结构体的一个成员指针的移动来不断读取,而文件指针的值不能动,还要用它来关闭文件。

三个特殊文件指针stdin、stdout、stderr

  • stdin:标准输入,默认为当前终端(键盘,对操作系统看来设备的读写是对设备文件的读写),使用scanf、getchar时默认从stdin文件指针对应的文件(不是磁盘文件,而是设备文件)中获取数据。
  • stdout:标准输出,默认为当前终端(屏幕),printf、puts默认输出信息到此文件指针指向的文件,如果让stdout改为指向一个txt文件,那么使用printf和puts时就会将内容输入到txt文件了。
  • stderr:标准错误,默认为当前终端(屏幕),使用perror函数时默认输出信息到此终端。

文件的打开与关闭

  • 对文件的操作无非读或写,但在对文件操作之前必须先进行一个步骤,即打开文件。打开的时候可以选择打开模式,即读模式,写模式等。

  • fopen()函数用来打开文件,如果打开成功,则返回一个文件指针。如果打开失败,则返回NULL,可以根据返回值是不是NULL来判断是否成功打开文件。

  • 文件打开失败有三种可能:
    ** 一是找不到文件,即文件不存在或路径写错了
    ** 二是没有权限
    ** 三是打开文件超出上限,每个进程打开文件的数目是有限制的,一般不超过65535个

  • 文件的打开模型如下,注意下边是windows中的情况,Linux中可能稍有差别。

  • 文件操作完之后必须要关闭,即使用fclose()函数即可,其参数就是对应的文件指针。

文本文件的顺序读写

写文件fputc()

  • 第二个参数为文件指针,需要注意用fopen()打开文件的时候一定要选择写模式,然后才能写入信息。比如用w模式,这样写入的内容会覆盖之前的内容,而用a模式则会把内容追加。

读文件fgetc()

  • 别看返回值是int,用char接收完全没问题,毕竟char可以看成是单字节整数。

  • 需要注意的是,连续调用fgetc()函数是能连续读取文本文件中的字符的,但这个过程中不是文件指针在移动,而是FILE结构体中的光标在移动。

文本文件结束标志

  • EOF = -1,即为文件结束标志。为什么是-1呢,因为读取的是文本文件,文本文件中如果都是ascii编码的字符的话,那么其范围是0到255,肯定不包括-1的,因此可以用-1来作为文件结束的标志。

按行读写文本文件

写文件fputs()

  • fputs()用于把一个字符串写到一个文件指针对应的文件中去,字符串结束符'\0'不写入文件,问题是,会不会自动在文件中加入换行符?

读文件fgets()

  • fgets()用来读文件,可以指定读取的字符数,注意,当设定读取size个时,实际上最多读size-1个,因为要在最后加上"\0"。

文本文件的格式化输入输出

写文件fprintf()

  • 功能是把格式化字符串写入到文件中

读文件fscanf()

  • 功能是从文件中读取出格式化字符串,前提是文件中内容确实是按照格式化字符串的形式存储的

按块二进制读写文件fread、fwrite

写文件fwrite()

  • 意思是将内存中ptr指向的字符串写到文件流stream对应的文件中去,其中size是每次写入的字节数(块的大小),nmemb是写入的次数(块的数量),二者配合保证将所有数据写到文件中去。注意“\0”不会被读取写入。
  • 之所以说是二进制读写,是因为fwrite是完全按字节来从源指针ptr中读取数据并写入目标文件的,而并不在于实际读写的是什么字符,只是一些二进制表示向量。

读文件fread()

  • ptr是用来存放读取出来的数据的内存空间,size是一次读取的字节数(块的大小),nmemb是读取的次数(块的数量),stream是已经打开的文件指针。

文本文件与二进制文件的结尾标志

EOF

  • EOF本质上是一个宏常量,#define EOF (-1),EOF只能作为文本文件的结束标志,因为文本文件中数据都是以字符的ASCII码值的形式存放的,而ASCII值是不包含-1的,因此可以用EOF作为结尾标识符。但是当把数据以二进制形式存放文件中时,会有-1出现。因此需要新的判断标准。

feof()函数

  • feof()函数既可以判断二进制文件,也可以判断文件文件

windows和Linux文本文件的区别

  • 注意,虽然windows和linux系统中对文件存储时最后的结果不一样,但是我们在操作文件的时候不必操心这一点,因为比如windows,读文件的时候也会把'\r'自动去掉。

获取文件状态

  • stat()函数用于获取一个文件的状态信息,第一个参数时文件路径,第二个参数是用来存文件状态信息的内存区。

文件的随机读写

  • fseek()函数,通过更改文件光标来改变文件读写的位置,因为文件指针我们绝对不能动,因此只能动文件光标了。

  • ftell()函数,获取文件光标的当前读写位置

  • rewind()函数,充值文件光标到开头

删除与重命名文件

  • remove函数删除文件
  • rename重命名文件

文件缓冲区

缓冲区概念

  • ANSI C 标准采用缓冲文件系统处理数据文件。
  • 缓冲文件系统是指系统自动地在内存区为程序中每一个正在使用地文件开辟一个文件缓冲区。
  • 当从内存中向磁盘输出数据时,必须先送到内存中地缓冲区,装满缓冲区后才一起送到磁盘去。
  • 当从磁盘中读取数据时,一次从磁盘文件中将一批数据输入到内存缓冲区中,充满缓冲区,然后再从缓冲区中逐个地将数据送到程序数据区,交给程序变量。
  • 使用缓冲区可以避免cpu和磁盘之间的频繁交互,从而提升效率

更新缓冲区fflush函数

scanf之后接上getchar

  • 目的即是,scanf会导致最后一个换行符留在缓冲区中,因此需要用getchar来把这个换行符读出来,防止影响以后的程序。
posted @   肖肖凯  阅读(317)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示