Loading

1 文件驱动器

文件驱动器一般被分为物理驱动器和逻辑驱动器。一个硬盘就是一个物理驱动器,而被系统自动编号的d,e,f等盘符,就是逻辑驱动器。物理驱动器是实实在在能看到的东西,如硬盘驱动器(简称硬盘)、光盘驱动器(简称光驱)、软盘驱动器(简称软驱)。电脑上有几个这样的物理硬件,那就有几个物理驱动器。

新硬盘开始使用前,必须对其进行分区。为了更好地利用硬盘空间,我们通常将其整体空间分成若干个区域,我们在操作系统上看硬盘,比如说Windows的“我的电脑”中,我们看到有“本地磁盘(C)”、“本地磁盘(D)”、“本地磁盘(E)”等,看起来好像有多个硬盘(多个物理驱动器也会表现为上述的形式),其实在逻辑上它们是在一块硬盘上的,这些硬盘分区,称之为逻辑驱动器。逻辑驱动器可以被格式化并指派驱动器号。

至于软盘和光盘,我们一般是不作分区的,若安装上软驱和光驱后,在“我的电脑”里显示“软盘驱动器(或可移动磁盘)(A)”、“CD-ROM(或CD-RW、DVD)驱动器(M)”(M为驱动器号)等,它们都是物理驱动器。不过,一些软件需要读写软盘或必须在光盘上运行,于是便有了一些软件,能将硬盘上的一部分空间模拟成软盘或光盘,使我的电脑中有多个软盘或光盘驱动器,这些我们把它们称为虚拟驱动器而不属于逻辑驱动器的。

硬盘分区有三种,主磁盘分区、扩展磁盘分区、逻辑分区。一个硬盘可以有一个主分区,一个扩展分区,也可以只有一个主分区没有扩展分区。逻辑分区可以若干。 主分区是硬盘的启动分区,他是独立的,也是硬盘的第一个分区,分出主分区后,其余的部分可以分成扩展分区,一般是剩下的部分全部分成扩展分区,也可以不全分,那剩的部分就浪费了。 但扩展分区是不能直接用的,他是以逻辑分区的方式来使用的,所以说扩展分区可分成若干逻辑分区。他们的关系是包含的关系,所有的逻辑分区都是扩展分区的一部分。

2 什么是文件

文件通常是在磁盘或固态硬盘上的一段已命名的存储区。对于操作系统而言,文件更复杂一些,其会包含一些额外的数据用于确定文件的种类。而对于一名普通程序员而言,我们更关心的是如何利用程序处理文件。

所有的文件内容都以二进制形式存储。在C语言中,文件被分为两类:若其中的二进制值代表字符编码,则其为文本文件;若其中的二进制值代表数值数据或图片或音乐编码等,则其为二进制文件。因此,C语言提供了文本模式和二进制模式两种方法对文件进行处理。然而,在UNIX和Linux系统下,这两种模式的实现完全相同。

对于Linux/Windows等系统而言,存在3个标准文件,它们被称为标准输入标准输出标准错误输出,C程序会自动打开这3个文件。在默认情况下,标准输入是系统的普通输入设备,即键盘;标准输出和标准错误输出是系统的普通输出设备,即显示屏。

如果采用文件重定向,则可将其他文件视作标准输入或标准输出。而对于标准错误输出,其逻辑稍微有点不同。即使采用重定向的方法将输出指定给文件,发送至标准错误输出的内容仍然会被发送到屏幕上。

3 标准IO

标准文件文件指针
标准输入stdin
标准输出stdout
标准错误stderr

fopen

/**
 * @brief 打开文件
 * @param pathname 文件的绝对路径
 * @param mode 文件打开的模式
 * @return 文件句柄(打开成功:文件流指针; 打开失败:NULL)
*/
FILE *fopen(const char *pathname, const char *mode);

/* mode参数: 
 * r或rb    以只读方式打开一个文本文件(不创建文件,文件不存在则报错)
 * w或wb    以写方式打开文件(如果文件存在则清空文件,文件不存在则创建一个文件)
 * a或ab    以追加方式打开文件,在末尾添加内容,若文件不存在则创建文件
 * r+或rb+  以可读、可写的方式打开文件(不创建新文件)
 * w+或wb+  以可读、可写的方式打开文件(如果文件存在则清空文件,文件不存在则创建一个文件)
 * a+或ab+  以添加方式打开文件,打开文件并在末尾更改文件,若文件不存在则创建文件
*/

fclose

/**
 * @brief 关闭文件
 * @param stream 文件流指针(文件句柄)
 * @note 根据文件句柄关闭文件。此动作让缓冲区的数据写入文件中,并释放系统所提供的文件资源。
 * @return 0:关闭成功; EOF(-1): 关闭失败
*/
int fclose(FILE *stream);

fgetc

/**
 * @brief 根据文件句柄读取一个字符
 * @param stream 文件流指针(文件句柄)
 * @return 成功:返回读取的字符的ASCII码值; 失败:EOF(-1)
*/
int fgetc(FILE *stream);

fputc

/**
 * @brief 根据文件句柄写入一个字符
 * @param stream 文件流指针(文件句柄)
 * @param ch 要写入的字符的ASCII码值(将ch转换为unsigned char后写入stream指定的文件中)
 * @return 成功:返回写入的字符的ASCII码值; 失败:EOF(-1)
*/
int fputc(int ch, FILE *stream);

fgets

/**
 * @brief 根据文件句柄读取字符串
 * @param s 字符串缓存空间首地址
 * @param size 欲读取的字符串大小
 * @param stream 文件流指针(文件句柄)
 * @note 在读取到换行符、或读到文件结尾、或已读取size - 1个字符后停止, 并在字符串末尾自动加上'\0'
 * @note 在读取到换行符时会将换行符也读入
 * @return 成功:返回读取的字符串首地址s; 失败:NULL
*/
char *fgets(char *s, int size, FILE *stream);

fputs

/**
 * @brief 根据文件句柄写入字符串
 * @param s 字符串缓存空间首地址
 * @param stream 文件流指针(文件句柄)
 * @note 字符串结束符 '\0'  不写入文件
 * @return 成功:返回写入文件的字符; 失败:EOF
*/
int fputs(const char *s, FILE *stream);

fread

/**
 * @brief 根据文件句柄读取数据
 * @param ptr 数据缓存空间首地址
 * @param size 读取的数据块大小
 * @param nmemb 读取的数据块个数
 * @param stream 文件流指针(文件句柄)
 * @note 读取文件数据总大小为:size * nmemb
 * @return 成功:实际读取到缓存的数据块个数,如果此值比nmemb小,但大于0,说明读到文件的结尾; 失败:0
*/
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

fwrite

/**
 * @brief 根据文件句柄写入数据
 * @param ptr 数据缓存空间首地址
 * @param size 写入的数据块大小
 * @param nmemb 写入的数据块个数
 * @param stream 文件流指针(文件句柄)
 * @note 写入文件数据总大小为:size * nmemb
 * @return 成功:实际写入文件数据的块数目,此值和 nmemb 相等; 失败:0
*/
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

ftell

/**
 * @brief 获取文件句柄的读写指针索引
 * @param stream 文件流指针(文件句柄)
 * @return 成功:当前文件流(文件光标)的读写位置; 失败:-1
*/
long ftell(FILE *stream);

fseek

/**
 * @brief 移动文件句柄的读写指针索引
 * @param stream 文件流指针(文件句柄)
 * @param offset 文件读写指针相对于whence位置的偏移量
 * @param whence SEEK_SET:文件开头
                 SEEK_CUR:当前位置
                 SEEK_END:文件末尾
 * @return 成功:0; 失败:-1
*/
int fseek(FILE *stream, long offset, int whence);

rewind

/**
 * @brief 移动文件句柄的读写指针到文件头
 * @param stream 文件流指针(文件句柄)
 * @note 即将文件读写指针的索引置0
*/
void rewind (FILE *stream);

fprintf

/**
 * @brief 根据文件句柄, 写入格式化字符串到文件中
 * @param stream 文件流指针(文件句柄)
 * @param format 按需的格式化字符串
 * @note 成功:返回写入的字符串总数; 失败:-1
*/
int fprintf(FILE *stream, const char *format, ...)

fscanf

/**
 * @brief 根据文件句柄, 读取格式化字符串
 * @param stream 文件流指针(文件句柄)
 * @param format 按需的格式化字符串
 * @note 成功:返回成功匹配和赋值的个数; 失败:EOF
*/
int fscanf(FILE *stream, const char *format, ...)

fgetpos

/**
 * @brief 获取流 stream 的当前文件位置,并把它写入到 pos
*/
int fgetpos(FILE *stream, fpos_t *pos)

fsetpos

/**
 * @brief 设置流 stream 的文件位置。参数 pos 是由函数 fgetpos 给定的位置
*/
int fsetpos(FILE *stream, const fpos_t *pos)

ungetc

/**
 * @brief 将字符c推入到指定流 stream 中,以便它是下一个被读取到的字符
*/
int ungetc(int c, FILE *stream)

fflush

/**
 * @brief 刷新流 stream 的输出缓冲区
 * @return 成功:返回0; 失败:返回EOF
*/
int fflush(FILE *stream)

setvbuf

/**
 * @brief 定义流 stream 应如何缓冲
 * @param stream 文件流指针(文件句柄) 
 * @param buffer 文件数据缓冲区
 * @param mode 文件缓存模式
 * @param size 文件数据缓冲区大小, 以字节为单位
 * @note 应在打开文件后, 且未对流进行其他操作之前, 调用该函数
 * @return 成功:返回0; 失败:非0值
*/
int setvbuf(FILE *stream, char *buffer, int mode, size_t size)

/* mode参数 */
_IOFBF:全缓冲,对于输出,数据在缓冲填满时被一次性写入。对于输入,缓冲会在请求输入且缓冲为空时被填充。
_IOLBF:行缓冲,对于输出,数据在遇到换行符或者在缓冲填满时被写入。对于输入,缓冲会在请求输入且缓冲为空时被填充,直到遇到下一个换行符。
_IONBF:无缓冲,不使用缓冲。每个 I/O 操作都被即时写入。buffer 和 size 参数被忽略。

feof

/**
 * @brief 检查与流stream关联的文件是否到文件尾
 * @return 如果检查到了文件尾, 则返回非0值, 否则返回0
*/
int feof(FILE *stream)

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

👤本站访客数: 👁️本站访问量: