从零开始的敲代码生活--Linux应用软件(文件操作基础1)

一、文件基础概念

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,可用catod -c查看

3. Linux下文件操作方法

  • 标准IO:C库函数,#include <stdio.h>,例如printfscanf
  • 文件IO:系统调用,由Linux内核提供接口

文件操作通用流程:

  1. 打开文件
  2. 读写文件
  3. 关闭文件

man手册使用:

  1. Linux命令:man 1 ls
  2. 系统调用:man 2 open
  3. 库函数:man 3 fopen

二、标准IO

文件流:读写过程中的字节流,标准IO操作面向FILE*文件流指针。

系统默认预先打开三个流:

文件流 对应设备 说明
stdin 键盘 标准输入流
stdout 终端显示屏 标准输出流
stderr 终端显示屏 标准错误流

1. fopen 打开文件

复制代码
FILE *fopen(const char *pathname, const char *mode);

参数:

  • pathname:文件路径名称
  • mode打开模式
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;   /* 夏令时 */
};
相关推荐
潘潘的嵌入式日记2 小时前
I²C 从机接收总被覆盖?双缓冲要在 STOP 时交接
c语言·开发语言·单片机
闲云野鹤在人间3 小时前
OpenStack架构介绍和安装流程
linux·网络·架构·openstack
我命由我123453 小时前
Linux - Linux/POSIX 路径斜杠折叠规则
linux·运维·服务器·android studio·android jetpack·android-studio·android runtime
xx~t3 小时前
嵌入式——Linux软件编程——网络1
linux·c语言·网络·vscode·网络协议
Uncertainty!!4 小时前
Linux 主机无法完成校园网认证排查记录:从 DHCP、ARP 到 Portal 认证流程分析
linux·运维·服务器
神威难绷泪4 小时前
Linux消息队列 & 共享内存 笔记
linux·消息队列·共享内存
mounter6255 小时前
突破零停机演进:Linux 内核 Live Update Orchestrator (LUO) 架构设计与热升级演进
linux·服务器·linux kernel·kernel·kho·luo
波多利希最高礼仪的握力器5 小时前
安全复制SCP
linux·服务器·安全
xiaoye-duck5 小时前
《Linux网络编程·加餐》进程间关系与守护进程
linux·网络