云计算百科
云计算领域专业知识百科平台

关于linux操作系统下的文件操作方法:

以下是对笔记中 Linux 文件操作(标准 I/O 为主) 知识点的系统总结,包含核心概念梳理、补充细节,并以表格整理标准 I/O 函数的参数与功能:


一、Linux 应用开发核心方向

笔记围绕 Linux 下的软件开发 展开,核心方向包括:

方向说明关联知识点
文件操作 对 Linux 各类文件(块设备、字符设备等)进行读写控制 文件类型、标准 I/O/文件 I/O 函数
多任务 通过进程、线程实现程序并行/并发执行 进程创建(fork)、线程管理等
网络编程 实现网络数据传输、通信 Socket 编程、TCP/UDP 协议等
网络服务器构建 开发支持网络请求的服务程序 HTTP 协议、套接字监听/响应逻辑
数据库 数据持久化存储与管理 MySQL、SQLite 等数据库操作

二、Linux 文件类型(7 种)

Linux 中“一切皆文件”,通过 ls -l 可查看文件类型(首字符标识 ):

文件类型首字符类型说明典型应用场景示例/备注
b 块设备文件 存储设备(硬盘、U盘 ) /dev/sda(硬盘分区 )
c 字符设备文件 输入输出设备(键盘、显示器 ) /dev/tty(终端 )、/dev/usb
d 目录文件 存储文件/子目录的“容器” 任意文件夹(如 /home )
普通文件 存储文本、二进制、图片等数据 .c 源码、.txt 文档、可执行文件
l 软链接文件(符号链接 ) 快捷方式,指向其他文件/目录的路径 ln -s 原文件 软链接名 创建
s 套接字文件 进程间网络通信(本地/网络套接字 ) /var/run/mysqld/mysqld.sock
p 管道文件 进程间通信(匿名/命名管道 ) mkfifo 管道名 创建

三、文件操作核心流程

无论标准 I/O 还是文件 I/O,均遵循 “打开 → 读写 → 关闭” 三步:

步骤说明标准 I/O 关键函数文件 I/O 关键函数(补充)
打开 关联文件与程序,获取操作句柄 fopen(返回 FILE* 流指针 ) open(返回文件描述符 fd )
读写 按字符、行、数据块读写内容 fgetc/fputc、fgets/fputs read/write(按字节流读写 )
关闭 释放资源,确保数据落盘 fclose close(关闭文件描述符 )

Linux fopen 函数打开模式(mode)说明表格,包含每种模式的含义、文件存在/不存在时的行为:

模式含义说明文件存在时的行为文件不存在时的行为典型应用场景
r 只读(read only) 打开文件,流指针指向文件开头 报错(返回 NULL) 读取配置文件、日志文件等
r+ 读写(read + write) 打开文件,流指针指向文件开头 报错(返回 NULL) 读取并修改现有文件内容
w 只写(write only,清空文件) 清空文件内容,流指针指向开头 创建新文件 覆盖写入全新内容(如日志重置)
w+ 读写(write + read,清空文件) 清空文件内容,流指针指向开头 创建新文件 覆盖写入并需要读取的场景
a 追加写(append only) 流指针移到文件末尾(保留内容) 创建新文件 日志追加、消息队列写入
a+ 追加读写(append + read) 读:指针在开头;写:指针在末尾 创建新文件 追加内容同时需要回读的场景

补充说明

  • 模式区分细节:

    • r/r+ 严格依赖文件已存在,否则直接失败(返回 NULL,需检查 errno 确认错误 )。
    • w/w+ 会强制清空现有文件(即使文件有内容 ),适合“覆盖写入”场景。
    • a/a+ 的写操作始终在文件末尾(无论指针如何移动 ),但读操作可自由调整指针位置(如 fseek )。
  • 实践建议:

    • 打开文件后务必检查返回值(if (fp == NULL) { perror("fopen"); exit(1); } )。
    • 不同模式的指针行为需注意,尤其是 a+ 模式(读和写的指针位置独立 )。
  • 跨平台差异:
    Windows 系统下,fopen 模式需额外区分文本模式("rt"/"wt" )和二进制模式("rb"/"wb" ),但 Linux 下无此严格区分(默认二进制模式 )。

  • 通过表格可直观对比各模式的行为差异,开发时根据需求(读、写、追加、覆盖 )选择对应模式即可。

    四、标准 I/O 函数总结(核心函数参数 & 功能表)

    标准 I/O 由 C 标准库(stdio.h)提供,基于 文件流(FILE*) 操作,核心函数如下:

    1. 文件打开:fopen

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

    要素说明
    功能 打开文件并返回 文件流指针(FILE*),失败返回 NULL。
    参数 – pathname:文件路径(如 "/tmp/test.txt")- mode:打开模式(见下表)
    返回值 成功返回 FILE* 流指针,失败返回 NULL(需检查 errno 定位错误)。
    需要检查返回值以判断文件是否成功打开:

    FILE *fp=fopen("./1.txt","w+");
    FILE *fp1=fp;
    if(fp==NULL)
    {
    printf("fopen error\\n");
    return -1;
    }

    2. 文件关闭:fclose

    int fclose(FILE *stream);

    要素说明
    功能 关闭文件流,刷新缓冲区,释放资源。
    参数 stream:fopen 返回的文件流指针(FILE*)。
    返回值 成功返回 0,失败返回 EOF(需检查 ferror(stream) 确认错误)。
    对文件执行fopen后别忘了执行fclose关闭打开的文件:
    3. 字符读写:fgetc / fputc
    • 读字符:fgetcint fgetc(FILE *stream);
    要素说明
    功能 从文件流 stream 读取一个字符(ASCII 码),流指针后移 1 字节。
    参数 stream:文件流指针(FILE*)。
    返回值 成功返回字符的 ASCII 码(int 类型,如 'A' 对应 65);失败/到文件末尾返回 EOF。
    代码:

    #include<stdio.h>
    int main(void)
    {
    FILE *fp=fopen("./1.txt","w+");
    FILE *fp1=fp;
    if(fp==NULL)
    {
    printf("fopen error\\n");
    return -1;
    }
    fputc('h',fp);
    fputc('e',fp);
    fputc('l',fp);
    fputc('l',fp);
    fputc('o',fp);
    fputc(' ',fp);
    fputc('w',fp);
    fputc('o',fp);
    fputc('r',fp);
    fputc('l',fp);
    fputc('d',fp);
    int ret=fgetc(fp1);
    /*if(ret==EOF)
    {
    printf("end of file or error\\n");
    }*/
    while(ret!=EOF)
    {
    printf("%c",ret);
    ret=fgetc(fp1);
    }
    fclose(fp);
    printf("fopen successful\\n");
    return 0;
    }

    • 写字符:fputcint fputc(int c, FILE *stream);
    要素说明
    功能 向文件流 stream 写入一个字符(c 的 ASCII 码),流指针后移 1 字节。
    参数 – c:要写入的字符(如 'A' 或直接传 ASCII 码 65)- stream:文件流指针
    返回值 成功返回写入字符的 ASCII 码;失败返回 EOF。
    代码:逐个字符读取:

    #include<stdio.h>
    int main(void)
    {
    FILE *fp=fopen("1.txt","r");
    int ret=fgetc(fp);
    /*if(ret==EOF)
    {
    printf("end of file or error\\n");
    }*/
    while(ret!=EOF)
    {
    printf("%c",ret);
    ret=fgetc(fp);
    }
    fclose(fp);
    printf("fopen successful\\n");
    return 0;
    }

    4. 行读写:fgets / fputs
    • 读一行:fgetschar *fgets(char *s, int size, FILE *stream);
    要素说明
    功能 从文件流 stream 读取一行数据(最多读 size-1 个字符,遇 \\n 或文件末尾停止 ),自动在 s 末尾加 \\0。
    参数 – s:存储数据的缓冲区(字符数组,如 char buf[1024] )- size:缓冲区大小(需 >1,预留 \\0 空间 )- stream:文件流指针
    返回值 成功返回 s 缓冲区地址;失败/到文件末尾返回 NULL。
    代码:

    #include<stdio.h>
    int main(int argc, const char *argv[])
    {
    FILE *PGS=fopen("./4.txt","r");
    if(PGS==NULL)
    {
    printf("fopen error\\n");
    return -1;
    }
    char s[100]={0};

    while(1)
    {
    char *p=fgets(s,sizeof(s),PGS);
    if(p==NULL)
    {
    break;
    }
    printf("%s\\n",p);
    }
    fclose(PGS);
    return 0;
    }

    • 写一行:fputsint fputs(const char *s, FILE *stream);
    要素说明
    功能 向文件流 stream 写入字符串(s 内容,不自动加 \\n,需手动添加 )。
    参数 – s:要写入的字符串(以 \\0 结尾,如 "hello" )- stream:文件流指针
    返回值 成功返回非负整数(通常是写入字符数 );失败返回 EOF。
    代码:

    #include<stdio.h>
    int main(int argc , const char *argv[])
    {
    FILE *FP=fopen("./4.txt","w");
    if(FP==NULL)
    {
    printf("fopen error\\n");
    return -1;
    }
    char s[100]={"china!\\n"};
    int ret=fputs(s,FP);
    if(ret==EOF)
    {
    printf("fputs error!\\n");
    return -1;
    }

    return 0;
    }

    5. 数据块读写:fread / fwrite(补充)

    size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
    size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

    要素说明
    功能 按数据块读写文件(适合二进制文件,如结构体、图片 )。
    参数 – ptr:缓冲区地址(读时存数据,写时取数据 )- size:单个数据块大小(字节 )- nmemb:数据块数量- stream:文件流指针
    返回值 实际读写的数据块数量(size_t );失败或到末尾可能小于 nmemb。

    五、补充细节 & 易错点

  • 文件流指针移动:
    读写操作会改变流指针位置(如 fgetc 后指针后移 1 字符 ),同一程序中“写后直接读”需用 fseek 重置指针(如 fseek(stream, 0, SEEK_SET) 回到文件开头 )。

  • 缓冲区机制:
    标准 I/O 带用户态缓冲区,数据先写入缓冲区,再由系统决定何时刷入磁盘。需立即落盘时,调用 fflush(stream) 手动刷新。

  • 命令行参数:argc / argv
    主函数参数用于接收命令行输入:

    int main(int argc, char *argv[]);

    • argc:参数总个数(含程序名 )。
    • argv:参数数组,argv[0] 是程序路径/名称,argv[1] 开始是用户输入参数。
  • 六,主函数传参的使用方法

    以下是结合笔记内容,对 Linux C 主函数传参(argc/argv) 的总结与补充,用清晰的逻辑和示例说明用法:


    1、主函数传参基础概念

    在 Linux C 程序中,主函数 main 支持通过命令行传递参数,形式为:

    int main(int argc, char *argv[]);

    参数名含义
    argc 参数个数(argument count):包含程序名在内的所有命令行参数总数。
    argv 参数数组(argument vector):字符串数组,存储每个命令行参数的内容。
    2、传参规则与示例

    以笔记中示例 ./a.out aaa bbb 为例:

    命令行输入argc 值argv 数组内容说明
    ./a.out aaa bbb 3 argv[0] = "./a.out" argv[1] = "aaa" argv[2] = "bbb" – argv[0] 固定为程序名/路径 – argv[1] 开始是用户传入的参数
    3、传参方法与场景
    1. 基础用法:命令行直接传参

    编译生成可执行文件(如 a.out )后,在终端通过以下方式传参:

    ./a.out 参数1 参数2 参数3 ...

    • 示例代码(遍历参数):#include <stdio.h>

      int main(int argc, char *argv[]) {
      printf("参数总数 argc = %d\\n", argc);
      for (int i = 0; i < argc; i++) {
      printf("argv[%d] = %s\\n", i, argv[i]);
      }
      return 0;
      }

    • 运行输出(输入 ./a.out aaa bbb ):参数总数 argc = 3
      argv[0] = ./a.out
      argv[1] = aaa
      argv[2] = bbb

    4、关键细节补充
  • argv 数组的结束标志:
    argv[argc] 固定为 NULL,可用于遍历参数时的终止判断:

    for (int i = 0; argv[i] != NULL; i++) {
    printf("argv[%d] = %s\\n", i, argv[i]);
    }

  • 参数的本质是字符串:
    argv 存储的是字符串,如需数值运算(如 ./app 10 20 ),需用 atoi/atof 转换:

    #include <stdlib.h>
    int num1 = atoi(argv[1]); // "10" → 10
    int num2 = atoi(argv[2]); // "20" → 20

  • 空格与引号处理:

    • 命令行参数以空格分隔,如需传递含空格的参数,用引号包裹:./app "hello world" # argv[1] = "hello world"(含空格)
    • 特殊字符(如 $、* )需用反斜杠转义(\\)或引号包裹。
  • 七、总结表格(标准 I/O 核心函数参数速查表)

    函数函数原型核心参数说明典型用途
    fopen FILE *fopen(const char *pathname, const char *mode); pathname(路径)、mode(打开模式) 打开文件并获取流指针
    fclose int fclose(FILE *stream); stream(文件流指针) 关闭文件、刷新缓冲区
    fgetc int fgetc(FILE *stream); stream(文件流指针) 读 1 个字符
    fputc int fputc(int c, FILE *stream); c(字符)、stream(文件流指针) 写 1 个字符
    fgets char *fgets(char *s, int size, FILE *stream); s(缓冲区)、size(最大读入字符 )、stream(文件流指针) 读 1 行数据
    fputs int fputs(const char *s, FILE *stream); s(字符串)、stream(文件流指针) 写 1 行字符串(不含 \\0 )

    使用fopen ,fputc,fgetc,fclose实现拷贝的功能:

    代码:

    #include<stdio.h>
    int main(int argc ,const char *argv[])
    {
    if(argc!=3)
    {
    printf("Usage : ./a.out <srcfile> <dstfile>\\n");
    return -1;
    }
    FILE *fp=fopen(argv[1],"r");
    if(fp==NULL)
    {
    printf("fopen error\\n");
    return -1;
    }
    FILE *fcp=fopen(argv[2],"w");
    if(fcp==NULL)
    {
    printf("fopen error\\n");
    return -1;
    }
    int ret =fgetc(fp);
    if(ret==EOF)
    {
    printf("end of file or error");
    }
    while(ret!=EOF)
    {
    fputc(ret,fcp);
    ret=fgetc(fp);
    }
    fclose(fp);
    fclose(fcp);
    return 0;
    }

    使用fopen,fgets,fputs,fclose库函数实现字符串的拷贝:

    代码

    #include<stdio.h>
    int main(int argc,const char *argv[])
    {
    if(argc!=3)
    {
    printf("Usage : copy <srcfile> <dstfile>\\n");
    return -1;
    }
    FILE *FGT=fopen(argv[1],"r");
    if(FGT==NULL)
    {
    printf("fopen error\\n");
    return -1;
    }
    FILE *FPT=fopen(argv[2],"w");
    if(FPT==NULL)
    {
    printf("fopen error\\n");
    return -1;
    }
    char s[100]={0};
    while(1)
    {
    char *fgt=fgets(s,sizeof(s),FGT);
    if(fgt==NULL)
    {
    break;
    }
    int fpt=fputs(fgt,FPT);
    if(fpt==EOF)
    {
    printf("fputs error\\n");
    return -1;
    }
    }

    fclose(FGT);
    fclose(FPT);
    return 0;
    }

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 关于linux操作系统下的文件操作方法:
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!