写文件头的算法流程及C代码实现

简介: 一、问题描述       将多条记录写入文件中,每条记录占一行。每写入一条记录,要计算当前文件中所有记录的大小(精确到字节)和记录条数,并写到文件的第一行(即文件头)。

一、问题描述

       将多条记录写入文件中,每条记录占一行。每写入一条记录,要计算当前文件中所有记录的大小(精确到字节)和记录条数,并写到文件的第一行(即文件头)。为了便于区分,文件记录的大小和文件中记录条数各占10个字节,左对齐,不足的位补以空格。

 

二、算法流程

三、C代码实现

/**********************************************************************
* 版权所有 (C)2015, Zhou Zhaoxiong。
*
* 文件名称:WriteFileHeader.c
* 文件标识:无
* 内容摘要:测试文件头的写入
* 其它说明:无
* 当前版本:V1.0
* 作    者:Zhou Zhaoxiong
* 完成日期:20150113
*
**********************************************************************/
#include 
  
   
#include 
   
   
    
#include 
    
    
     


// 重定义数据类型
typedef signed   char       INT8;
typedef unsigned char       UINT8;
typedef unsigned int        UINT32;
typedef signed   int        INT32;

// 函数声明
void WriteToFile(UINT8 *pszContentLine);
INT32 main();

/**********************************************************************
* 功能描述:主函数
* 输入参数:无
* 输出参数:无
* 返 回 值:无
* 其它说明:无
* 修改日期        版本号     修改人            修改内容
* -------------------------------------------------------------------
* 20150113        V1.0     Zhou Zhaoxiong        创建
***********************************************************************/
INT32 main()
{
    UINT8  szContentLine[1000] = {0};

    // 第一次写文件
    // 拼装写本地文件的内容
    snprintf(szContentLine, sizeof(szContentLine)-1, "1234|abcd|\r\n");
    // 将文件内容写入本地文件
    WriteToFile(szContentLine);
	
    // 第二次写文件
    // 拼装写本地文件的内容
    snprintf(szContentLine, sizeof(szContentLine)-1, "5678|efgh|\r\n");
    // 将文件内容写入本地文件
    WriteToFile(szContentLine);

    // 第三次写文件
    // 拼装写本地文件的内容
    snprintf(szContentLine, sizeof(szContentLine)-1, "4321|dcba|\r\n");
    // 将文件内容写入本地文件
    WriteToFile(szContentLine);

    return 0;                  // main函数返回0
}


/**********************************************************************
 * 功能描述: 写本地文件, 同时更新文件头
 * 输入参数: pszContentLine: 一条文件记录
 * 输出参数: 无
 * 返 回 值: 无
 * 其它说明: 文件头的长度为20字节, 前10字节为写入文件内容的大小, 后10字节为文件内容的条数
 * 修改日期            版本号            修改人           修改内容
 * ----------------------------------------------------------------------
*  20150113             V1.0          Zhou Zhaoxiong        创建
 ************************************************************************/
void WriteToFile(UINT8 *pszContentLine)
{
    INT8   szFileName[500]     = {0};
    FILE  *fp                  = NULL;
    UINT8  iIsNewCdrFile       = 0;
    UINT8  szFileHeader[100]   = {0};
    UINT8  szTmpBuf[50]        = {0};
    UINT32 iSize               = 0;
    UINT32 iCount              = 0;
    UINT32 iLen                = 0;
    
    if (NULL == pszContentLine)
    {
        printf("WriteToFile: input parameter is NULL.\n");
        return;
    }
    
    snprintf(szFileName, sizeof(szFileName)-1, "/home/zhou/zhouzhaoxiong/TestFile.txt");
    
    // 判断是否为新文件
    if (access(szFileName, 0) == -1)
    {
        iIsNewCdrFile = 1;     // 是新文件
    }
    else
    {
        iIsNewCdrFile = 0;
    }

    fp = fopen(szFileName, "a+");
    if (fp == NULL)
    {
         printf("WriteToFile: open file failed, file=%s\n", szFileName);
         return;
    }

    // 如果是新文件, 先写文件头
    if (iIsNewCdrFile == 1)
    {
        // 新话单文件, 写入文件头
        memset(szFileHeader, 0x00, sizeof(szFileHeader));
        memset(szFileHeader, ' ', 20);    
        strcat(szFileHeader, "\r\n");       // 回车换行符
	// 文件头第一部分, 文件内容的大小
        sprintf(szTmpBuf, "%d", strlen(pszContentLine)-2);   // 要去掉最后的回车换行符的大小, 因此这里要减去2
        memcpy(szFileHeader, szTmpBuf, strlen(szTmpBuf));

	// 文件头第二部分, 文件内容的条数
        sprintf(szTmpBuf, "%d", 1);   // 写入第一条
        memcpy(szFileHeader+10, szTmpBuf, strlen(szTmpBuf));

        printf("WriteToFile: now write header to file, Count of content=%s\n", szTmpBuf);
        fputs(szFileHeader, fp);
    }

    fputs(pszContentLine, fp);
    fflush(fp);

    fclose(fp);
    fp = NULL;     // 写入完毕要在关闭文件的同时置文件指针为空

    // 更新文件头
    if (iIsNewCdrFile == 0)       // 文件已存在
    {
        fp = fopen(szFileName, "r+");
        if (fp == NULL)
        {
             printf("WriteToFile: open file for updating header failed, file=%s\n", szFileName);
             return;
        }
    
        // 已有话单文件, 更新文件头
        memset(szFileHeader, 0x00, sizeof(szFileHeader));
        fseek(fp, 0, SEEK_SET);        // 文件第一行
        fread(szFileHeader, 20, 1, fp);
        fflush(fp);
        
	// 更新文件内容的大小
        memset(szTmpBuf, 0x00, sizeof(szTmpBuf));
        memcpy(szTmpBuf, szFileHeader, 10);
        iSize = atoi(szTmpBuf);    // 原大小
        sprintf(szTmpBuf, "%d", iSize+strlen(pszContentLine)-2);
        iLen = strlen(szTmpBuf);
        memcpy(szFileHeader, szTmpBuf, iLen);

	// 更新文件内容的条数
        memset(szTmpBuf, 0x00, sizeof(szTmpBuf));
        memcpy(szTmpBuf, szFileHeader+10, 10);
        iCount = atoi(szTmpBuf);
        sprintf(szTmpBuf, "%d", iCount+1);
        iLen = strlen(szTmpBuf);
        memcpy(szFileHeader+10, szTmpBuf, iLen);

        printf("WriteToFile: now update file header, Count of content=%s\n", szTmpBuf);
        fseek(fp, 0, SEEK_SET);
        fwrite(szFileHeader, 20, 1, fp);
        fflush(fp);

        fclose(fp);
        fp = NULL;
    }
}

    
    
   
   
  
  

 

四、程序说明

        (1) 本程序在Linux环境下用makefile文件进行编译,makefile文件的内容如下:

WriteFileHeader : WriteFileHeader.c

       gcc -c -g WriteFileHeader.c

       gcc -g -o release/WriteFileHeader WriteFileHeader.o

       rm *.o

        (2) 本程序中使用了多个文件处理函数,如:fopenfputsfflushfclosefseekfreadfwrite等。各位读者可以据此体会不同文件处理函数的用法。

        (3) 本程序演示了三次文件记录的写入过程,大家可以根据自身所需用不同的记录来对程序进行测试。

 

五、程序运行结果

        用makefile文件对程序进行编译之后,转到release目录下,执行“WriteFileHeader”命令,结果如下:

WriteToFile: now write header to file, Count of content=1

WriteToFile: now update file header, Count of content=2

WriteToFile: now update file header, Count of content=3

       查看TestFile.txt文件,内容如下:


---------------------------------------

2016年4月28日修改程序:

/**********************************************************************
* 版权所有 (C)2015, Zhou Zhaoxiong。
*
* 文件名称:WriteFileHeader.c
* 文件标识:无
* 内容摘要:测试文件头的写入
* 其它说明:无
* 当前版本:V1.0
* 作    者:Zhou Zhaoxiong
* 完成日期:20150113
*
**********************************************************************/
#include 
  
   
#include 
   
   
    
#include 
    
    
     
#include 
     
     
    
    
   
   
  
  



目录
相关文章
|
1天前
|
存储 算法 Serverless
剖析文件共享工具背后的Python哈希表算法奥秘
在数字化时代,文件共享工具不可或缺。哈希表算法通过将文件名或哈希值映射到存储位置,实现快速检索与高效管理。Python中的哈希表可用于创建简易文件索引,支持快速插入和查找文件路径。哈希表不仅提升了文件定位速度,还优化了存储管理和多节点数据一致性,确保文件共享工具高效运行,满足多用户并发需求,推动文件共享领域向更高效、便捷的方向发展。
|
5天前
|
存储 算法 安全
基于哈希表的文件共享平台 C++ 算法实现与分析
在数字化时代,文件共享平台不可或缺。本文探讨哈希表在文件共享中的应用,包括原理、优势及C++实现。哈希表通过键值对快速访问文件元数据(如文件名、大小、位置等),查找时间复杂度为O(1),显著提升查找速度和用户体验。代码示例展示了文件上传和搜索功能,实际应用中需解决哈希冲突、动态扩容和线程安全等问题,以优化性能。
|
1月前
|
存储 算法 程序员
C 语言递归算法:以简洁代码驾驭复杂逻辑
C语言递归算法简介:通过简洁的代码实现复杂的逻辑处理,递归函数自我调用解决分层问题,高效而优雅。适用于树形结构遍历、数学计算等领域。
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
67 1
|
2月前
|
存储 缓存 算法
通过优化算法和代码结构来提升易语言程序的执行效率
通过优化算法和代码结构来提升易语言程序的执行效率
|
2月前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
2月前
|
算法 测试技术 开发者
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗;代码审查通过检查源代码发现潜在问题,提高代码质量和团队协作效率。本文介绍了一些实用的技巧和工具,帮助开发者提升开发效率。
53 3
|
2月前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
3月前
|
存储 缓存 算法
如何通过优化算法和代码结构来提升易语言程序的执行效率?
如何通过优化算法和代码结构来提升易语言程序的执行效率?
|
3月前
|
搜索推荐
插入排序算法的讲解和代码
【10月更文挑战第12天】插入排序是一种基础的排序算法,理解和掌握它对于学习其他排序算法以及数据结构都具有重要意义。你可以通过实际操作和分析,进一步深入了解插入排序的特点和应用场景,以便在实际编程中更好地运用它。

热门文章

最新文章