一、文件基础概念
1. 文件
程序变量、数组、数据结构存放在内存;文件存储在外存(硬盘)。
| 读写速度 | 快 | 比内存慢 |
| 数据保持 | 程序执行结束、掉电数据丢失 | 掉电数据不丢失 |
| 空间/价格 | 空间小,价格昂贵 | 空间大,相对内存价格便宜 |
文件用于长期保存掉电不丢失的数据。Linux一切皆文件,硬件也通过文件接口给应用层操作。
2. Linux下文件类型
ls -l 文件名可以查看文件信息。示例:
-rwxrwxr-x 1 linux linux 19856 Aug 14 19:20 a.out
Linux一共7种文件类型:
| b | block 块设备文件 | 存储类文件 | 硬盘 |
| c | character 字符设备文件 | 字符设备 | 鼠标、键盘、显示器 |
| d | directory 目录文件 | 文件夹 | 普通文件夹 |
| – | regular 普通文件 | 普通文件 | main.c、txt、jpg、可执行程序 |
| l | link 软连接文件 | 快捷方式(符号链接) | — |
| s | socket 套接字文件 | 网络编程 | — |
| p | pipe 管道文件 | 进程间通信 | — |
普通文件分为:
- 二进制文件:存储二进制01序列,如a.out、png、mp3
- ASCII文本文件:存储字符,如.c、.h、.txt,可用cat、od -c查看
3. Linux下文件操作方法
- 标准IO:C库函数,#include <stdio.h>,例如printf、scanf
- 文件IO:系统调用,由Linux内核提供接口
文件操作通用流程:
man手册使用:
二、标准IO
文件流:读写过程中的字节流,标准IO操作面向FILE*文件流指针。
系统默认预先打开三个流:
| stdin | 键盘 | 标准输入流 |
| stdout | 终端显示屏 | 标准输出流 |
| stderr | 终端显示屏 | 标准错误流 |
1. fopen 打开文件
FILE *fopen(const char *pathname, const char *mode);
参数:
- pathname:文件路径名称
- mode打开模式
| "r" | 只读,文件必须存在 |
| "r+" | 读写,文件必须存在 |
| "w" | 只写;不存在创建,存在清空原有内容 |
| "w+" | 读写;不存在创建,存在清空原有内容 |
| "a" | 追加只写;不存在创建,写在文件末尾 |
| "a+" | 读写;读从开头,写向末尾追加 |
返回:成功返回FILE*,失败返回NULL。
2. fclose 关闭文件
int fclose(FILE *stream);
成功返回0,失败返回EOF(-1)。
注意:文件用完必须关闭,否则产生文件描述符泄露。
3. fputc 写入单个字符
int fputc(int c, FILE *stream);
putchar('a')等价于fputc('a',stdout)。 返回成功字符,失败返回EOF。
4. fgetc 读取单个字符
int fgetc(FILE *stream);
读到文件末尾/出错返回EOF。
fgetc+fputc实现文件拷贝(命令行传参argc/argv)
#include <stdio.h>
int main(int argc, const char *argv[])
{
if (argc < 3)
{
printf("Usage: ./a.out srcfile dstfile\\n");
return -1;
}
FILE *fpsrc = fopen(argv[1], "r");
FILE *fpdst = fopen(argv[2], "w");
if (NULL == fpsrc || NULL == fpdst)
{
printf("fopen error\\n");
return -1;
}
int ret = 0;
while (1)
{
ret = fgetc(fpsrc);
if (EOF == ret)
{
break;
}
fputc(ret, fpdst);
}
fclose(fpsrc);
fclose(fpdst);
return 0;
}
5. fputs 写字符串
int fputs(const char *s, FILE *stream);
将字符串写入文件,不会写入'\\0';成功返回>=0,失败返回EOF。
6. fgets 读取一行
char *fgets(char *s, int size, FILE *stream);
最多读取size‑1字节,末尾自动补'\\0';读到换行会保存换行符。
gets不安全不推荐使用;scanf遇到空格、tab、换行停止读取。
fgets+fputs实现文件拷贝函数
int file_cp(const char *srcfile, const char *dstfile)
{
FILE *fpsrc = fopen(srcfile, "r");
FILE *fpdst = fopen(dstfile, "w");
if (NULL == fpsrc || NULL == fpdst)
{
printf("fopen error\\n");
return -1;
}
char buff[1024] = {0};
while (NULL != fgets(buff, sizeof(buff), fpsrc))
{
fputs(buff, fpdst);
}
fclose(fpsrc);
fclose(fpdst);
return 0;
}
fgets/fputs适合文本文件,不适合二进制文件。
7. fwrite 块写
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
向文件写入nmemb个、每个大小size字节的数据单元;返回成功写入的单元个数。
8. fread 块读
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
从文件读取nmemb个单元到ptr内存;返回实际读到的单元数量。
9. 文件流定位
fseek:重定位读写位置
int fseek(FILE *stream, long offset, int whence);
- SEEK_SET:从文件起始位置偏移
- SEEK_CUR:从当前位置偏移
- SEEK_END:从文件末尾偏移
ftell:获取当前距离文件开头字节偏移
long ftell(FILE *stream);
rewind:将文件流直接回到文件开头
void rewind(FILE *stream);
获取文件大小示例
fseek(fp, 0, SEEK_END);
len = ftell(fp);
rewind(fp);
三、时间相关函数
头文件:#include <time.h>
1. time 获取时间戳(秒数)
time_t time(time_t *tloc);
获取从1970‑01‑01 00:00:00到当前的秒数。
2. ctime 将时间戳转为字符串时间
char *ctime(const time_t *timep);
3. localtime 将时间戳转为tm日历结构体
struct tm *localtime(const time_t *timep);
struct tm结构体成员:
struct tm {
int tm_sec; /* 秒 0‑60 */
int tm_min; /* 分 0‑59 */
int tm_hour; /* 时 0‑23 */
int tm_mday; /* 日期 1‑31 */
int tm_mon; /* 月份 0‑11 */
int tm_year; /* 年份,实际=tm_year+1900 */
int tm_wday; /* 星期 0‑6,周日=0 */
int tm_yday; /* 一年中的第几天 */
int tm_isdst; /* 夏令时 */
};
![第5章,[Win32 章节] :绘制填充区域-171主机测评](https://www.171host.com/wp-content/uploads/2026/08/20260828173251-6a91c6434b552-220x150.png)


