【文件操作:解锁高效读写与管理技巧】(下)

简介: 【文件操作:解锁高效读写与管理技巧】

【文件操作:解锁高效读写与管理技巧】(中):https://developer.aliyun.com/article/1424830


5.2 ftell - 返回文件指针相对于起始位置的偏移量


long int ftell ( FILE * stream );


  • 对于二进制流,这是从文件开头算起的字节数。
  • 对于文本流,数值可能没有实际意义,但仍可用于稍后使用 fseek 将位置恢复到相同位置(如果还有使用 ungetc 放回的字符待读取,则行为是未定义的)。


#include <stdio.h>
int main()
{
    FILE* pFile;
    long size;
    pFile = fopen("example.txt", "rb");
    if (pFile == NULL) 
        perror("Error opening file");
    else
    {
        fseek(pFile, 0, SEEK_END);   //文件末尾 
        size = ftell(pFile);
        fclose(pFile);
        pFile = NULL;
        printf("Size of example.txt: %ld bytes.\n", size);
    }
    return 0;
}


运行结果:



5.3 rewind - 让文件指针的位置回到文件的起始位置


void rewind ( FILE * stream );


  • 该函数将与流关联的位置指示器设置为文件的开头。
  • 成功调用此函数后,流相关的文件末尾和错误内部指示器将被清除,并且该流上先前调用 ungetc 的所有影响都将被丢弃。
  • 对于以更新模式打开(读写模式)的流,调用 rewind 允许在读和写之间切换。换句话说,它可以重新定位流的位置指示器到文件的开头,以便可以从头开始读取或写入数据。


#include <stdio.h>
int main()
{
    int n;
    FILE* pFile;
    char buffer[27];
    pFile = fopen("myfile.txt", "w+");
    for (n = 'A'; n <= 'Z'; n++)
        fputc(n, pFile);//输出 - 写文件
    rewind(pFile);//回到起始位置
    fread(buffer, 1, 26, pFile);//输入 - 读文件
    fclose(pFile);
    pFile = NULL;
    buffer[26] = '\0';
    puts(buffer);
    return 0;
}


运行结果:



6. 文本文件和二进制文件


  • 根据数据的组织形式,数据文件被称为文本文件或者二进制文件。
  • 数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。
  • 如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
  • 一个数据在内存中是怎么存储的呢?
  • 字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
  • 如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占4个字节(VS2013测试十六进制:10 27 00 00)。


#include <stdio.h>
int main()
{
  int a = 10000;
  FILE* pf = fopen("test.txt", "wb");
  fwrite(&a, 4, 1, pf);//二进制的形式写到文件中 - 输出
  fclose(pf);
  pf = NULL;
  return 0;
}


运行结果:



解读该文件:





7. 文件读取结束的判定


7.1 被错误使用的feof


牢记:在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否结束。

feof 的作用是:当文件读取结束的时候,判断是读取结束的原因是否是:遇到文件尾结束。

1. 文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )


例如:


fgetc 判断是否为 EOF .

fgets 判断返回值是否为 NULL .


2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。

例如:

fread判断返回值是否小于实际要读的个数


文本文件的例子:


#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    int c; // 注意:int,非char,要求处理EOF
    FILE* fp = fopen("test.txt", "r");
    if (!fp) {
        perror("File opening failed");
        return EXIT_FAILURE;
    }
    //fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
    while ((c = fgetc(fp)) != EOF) // 标准C I/O读取文件循环
    {
        putchar(c);
    }
    //判断是什么原因结束的
    if (ferror(fp))
        puts("I/O error when reading");//读取失败
    else if (feof(fp))
        puts("End of file reached successfully");//文件结束
    fclose(fp);
    fp = NULL;
    return 0;
}


二进制文件的例子:


#include <stdio.h>
enum
{
    SIZE = 5
};
int main(void)
{
    double a[SIZE] = { 1,2,3,4,5 };
    FILE* fp = fopen("test.bin", "wb"); // 必须用二进制模式
    fwrite(a, sizeof * a, SIZE, fp); // 写 double 的数组
    fclose(fp);
    double b[SIZE];
    fp = fopen("test.bin", "rb");
    size_t ret_code = fread(b, sizeof * b, SIZE, fp); // 读 double 的数组
    if (ret_code == SIZE) {
        puts("Array read successfully, contents: ");
        for (int n = 0; n < SIZE; ++n) 
            printf("%f ", b[n]);
        putchar('\n');
    }
    else { // error handling
        if (feof(fp))
            printf("Error reading test.bin: unexpected end of file\n");
        else if (ferror(fp)) {
            perror("Error reading test.bin");
        }
    }
    fclose(fp);
    fp = NULL;
    return 0;
}


文件拷贝(代码形式)


//data.txt的内容拷贝到data1.txt
#include<stdio.h>
int main()
{
  FILE* pfRead = fopen("data.txt","r");
  if (!pfRead)
  {
    perror("open file for read");
    return 1;
  }
  FILE* pfWrite = fopen("data1.txt", "w");
  if (!pfWrite)
  {
    perror("open file for write");
    fclose(pfRead);
    pfRead = NULL;
    return 1;
  }
  //读写文件 vb
  int ch = 0;
  while ((ch = fgetc(pfRead)) != EOF)
  {
    fputc(ch, pfWrite);
  }
  //关闭文件
  fclose(pfWrite);
  pfWrite = NULL;
  fclose(pfRead);
  pfRead = NULL;
  return 0;
}


运行结果:



8. 文件缓冲区


 ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。



fflush - 清空缓冲区,缓冲区写入文件


int fflush ( FILE * stream )


  • 如果给定的流是以写入方式打开的(或者以更新方式打开且最后一个 I/O 操作是输出操作),则会将其输出缓冲区中的所有未写数据写入文件。
  • 如果流是空指针,则会刷新所有这样的流。
  • 在其他所有情况下,行为取决于特定的库实现。在某些实现中,刷新以读取方式打开的流会导致其输入缓冲区被清空。
  • 调用此函数后,流仍然保持打开状态。
  • 当关闭文件时,无论是因为调用 fclose 还是因为程序终止,与其关联的所有缓冲区都会自动刷新。


#include <stdio.h>
#include <windows.h>
//VS2019 WIN10环境测试
int main()
{
  FILE* pf = fopen("test1.txt", "w");
  fputs("abcdef", pf);//先将代码放在输出缓冲区
  printf("睡眠10秒-已经写数据了,打开test1.txt文件,发现文件没有内容\n");
  Sleep(10000);
  printf("刷新缓冲区\n");
  fflush(pf);//刷新缓冲区时,才将出输缓冲区的数据写到文件(磁盘)
  //注:fflush 在高版本的VS上不能使用了
  printf("再睡眠10秒-此时,再次打开test1.txt文件,文件有内容了\n");
  Sleep(10000);
  fclose(pf);
  //注:fclose在关闭文件的时候,也会刷新缓冲区
  pf = NULL;
  return 0;
}


结论:


  • 因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。
  • 如果不做,可能导致读写文件的问题。
相关文章
|
5天前
|
人工智能 安全 API
CoPaw:5分钟部署你的 AI助理
源自阿里巴巴开源生态的个人 AI 助理——CoPaw。作为阿里倾力打造的开源力作,CoPaw 完美打通钉钉、飞书、Discord 等多平台对话通道,支持定时任务自动化。内置 PDF/Office 深度处理、新闻摘要等强大技能,更开放自定义扩展接口。坚持数据全程私有化部署,绝不上传云端,让每一位用户都能在大厂技术加持下,拥有安全、专属的智能助手。
|
8天前
|
人工智能 自然语言处理 JavaScript
2026年Windows+Ollama本地部署OpenClaw保姆级教程:本地AI Agent+阿里云上快速搭建
2026年OpenClaw凭借本地部署、私有化运行的特性,成为打造个人智能体的核心工具,而Ollama作为轻量级本地大模型管理工具,能让OpenClaw摆脱对云端大模型的依赖,实现**本地推理、数据不泄露、全流程私有化**的智能体验。本文基于Windows 11系统,从硬件环境准备、Ollama安装与模型定制、OpenClaw部署配置、技能扩展到常见问题排查,打造保姆级本地部署教程,同时补充阿里云OpenClaw(Clawdbot)快速部署步骤,兼顾本地私有化需求与云端7×24小时运行需求,文中所有代码命令均可直接复制执行,确保零基础用户也能快速搭建属于自己的本地智能体。
9658 77
|
6天前
|
人工智能 安全 JavaScript
阿里云上+本地部署OpenClaw(小龙虾)新手攻略:解锁10大必备Skills,零基础也能玩转AI助手
2026年,开源AI代理工具OpenClaw(昵称“小龙虾”)凭借“能实际做事”的核心优势,在GitHub斩获25万+星标,成为现象级AI工具。它最强大的魅力在于可扩展的Skills(技能包)系统——通过ClawHub插件市场的数百个技能,能让AI助手从简单聊天升级为处理办公、学习、日常事务的全能帮手。
5128 13
|
7天前
|
人工智能 自然语言处理 机器人
保姆级教程:Mac本地搭建OpenClaw及阿里云上1分钟部署OpenClaw+飞书集成实战指南
OpenClaw(曾用名Clawdbot、Moltbot)作为2026年最热门的开源个人AI助手平台,以“自然语言驱动自动化”为核心,支持对接飞书、Telegram等主流通讯工具,可替代人工完成文件操作、日历管理、邮件处理等重复性工作。其模块化架构适配多系统环境,既可以在Mac上本地化部署打造私人助手,也能通过阿里云实现7×24小时稳定运行,完美兼顾隐私性与便捷性。
5187 12
|
9天前
|
人工智能 JSON JavaScript
手把手教你用 OpenClaw + 飞书,打造专属 AI 机器人
手把手教你用 OpenClaw(v2026.2.22-2)+ 飞书,10分钟零代码搭建专属AI机器人!内置飞书插件,无需额外安装;支持Claude等主流模型,命令行一键配置。告别复杂开发,像聊同事一样自然对话。
5441 13
手把手教你用 OpenClaw + 飞书,打造专属 AI 机器人
|
4天前
|
人工智能 JavaScript Ubuntu
5分钟上手龙虾AI!OpenClaw部署(阿里云+本地)+ 免费多模型配置保姆级教程(MiniMax、Claude、阿里云百炼)
OpenClaw(昵称“龙虾AI”)作为2026年热门的开源个人AI助手,由PSPDFKit创始人Peter Steinberger开发,核心优势在于“真正执行任务”——不仅能聊天互动,还能自动处理邮件、管理日程、订机票、写代码等,且所有数据本地处理,隐私完全可控。它支持接入MiniMax、Claude、GPT等多类大模型,兼容微信、Telegram、飞书等主流聊天工具,搭配100+可扩展技能,成为兼顾实用性与隐私性的AI工具首选。
2593 6
|
2天前
|
人工智能 JavaScript 测试技术
保姆级教程:OpenClaw阿里云及本地部署+Claude Code集成,打造全能 AI 编程助手
在AI编程工具百花齐放的2026年,Anthropic推出的Claude Code凭借72.5%的SWE-bench测试高分、25倍于GitHub Copilot的上下文窗口,成为开发者追捧的智能编程助手。但单一工具仍有局限——Claude Code擅长代码生成与审查,却缺乏灵活的部署与自动化执行能力;而OpenClaw(前身为Clawdbot)作为开源AI代理框架,能完美弥补这一短板,通过云端与本地双部署,实现“代码开发-测试-部署”全流程自动化。
1353 13
|
4天前
|
人工智能 JavaScript API
阿里云及本地 Windows 部署(OpenClaw+Ollama)保姆级教程及技能扩展与问题排查
OpenClaw(原Clawdbot)作为2026年主流的开源AI智能体工具,具备系统级操作权限,能将自然语言指令转化为文件操作、程序控制等实际行为。搭配轻量级本地大模型管理工具Ollama,可实现本地推理、数据私有化存储的全闭环;而阿里云提供的云端部署方案,则能满足7×24小时稳定运行需求。本文将详细拆解2026年阿里云与本地(Windows 11系统)部署OpenClaw的完整流程,包含Ollama模型定制、技能扩展及常见问题排查,所有代码命令可直接复制执行,零基础用户也能快速上手。
1737 3

热门文章

最新文章