分批讀取檔案中資料的程式流程及其C代碼實現,流程代碼

來源:互聯網
上載者:User

分批讀取檔案中資料的程式流程及其C代碼實現,流程代碼

一、概述
在實際的軟體開發項目中,經常需要處理大量的檔案。某些檔案中包含了相當多的資料記錄數,如作者本人蔘與過的項目中,一個檔案中有好幾十萬條記錄。如果一次性將多條記錄讀入,則會花費大量的處理時間,且佔用大量的記憶體。
為此,要求對於包含大量資料記錄的檔案進行分批讀取操作,即每一輪讀取一定數目的資料記錄,待將這些記錄處理完成之後,再讀取下一批資料。本文介紹分批讀取檔案中資料的程式流程,並給出了C程式實現。

二、總體程式流程
實現分批讀取檔案中資料的程式流程1所示。

圖1 實現分批讀取檔案中資料的程式流程

三、C程式實現
本程式命名為BatchReadFile.c,具體代碼如下:

/*********************************************************************** 著作權 (C)2015, Zhou Zhaoxiong。** 檔案名稱:BatchReadFile.c* 檔案標識:無* 內容摘要:分批讀取檔案中的資料並列印出來* 其它說明:無* 目前的版本:V1.0* 作    者:Zhou Zhaoxiong* 完成日期:20150528***********************************************************************/#include <stdio.h>// 重定義資料類型typedef signed   int    INT32;typedef unsigned int    UINT32;typedef unsigned char   UINT8;// 宏定義#define ONCE_READ_COUNT    5      // 一次讀取的最大資料條數#define MAX_RECORD_LEN     50     // 每條資料的最大長度// 函式宣告INT32 ReadRecordFromFile(FILE *fp, UINT8 szRecordSet[][MAX_RECORD_LEN], UINT32 *piReadCnt);INT32 main();/*********************************************************************** 功能描述:主函數* 輸入參數:無* 輸出參數:無* 返 回 值:無* 其它說明:無* 修改日期        版本號碼         修改人           修改內容* -------------------------------------------------------------------* 20150528        V1.0     Zhou Zhaoxiong        建立***********************************************************************/INT32 main(){    UINT8  szFileName[256] = {0};     // 包含完整路徑的檔案名稱    FILE  *fp              = NULL;    // 檔案控制代碼    UINT32 iReadCnt        = 0;       // 一次讀取到的記錄數    UINT32 iRecCnt         = 0;       // 記錄數, 迴圈變數    UINT32 iReadTimes      = 0;       // 讀取檔案次數    INT32  iRetVal         = 0;       // 讀取檔案函數的傳回值    UINT8  szRecordSet[ONCE_READ_COUNT][MAX_RECORD_LEN] = {0};   // 存放從檔案中讀取到的記錄內容集    UINT8  szRecordInfo[MAX_RECORD_LEN]                 = {0};   // 存放從檔案中讀取到的每條記錄內容    // 擷取包含完整路徑的檔案名稱    strcpy(szFileName, "/home/zxin10/zhouzx/test/file/TestFile.txt");    // 開啟檔案     fp = fopen(szFileName, "r");    if (NULL == fp)   // 開啟失敗    {        printf("Open file %s failed!\n", szFileName);        return -1;    }    // 讀取檔案內容並列印出來    while (1)    {        iReadCnt = 0;        memset(szRecordSet, 0x00, sizeof(szRecordSet));          iRetVal = ReadRecordFromFile(fp, szRecordSet, &iReadCnt);         if (iRetVal == -1)   // 表示函數執行失敗, 直接退出        {            printf("Exec ReadRecordFromFile failed, please check!\n");            break;        }        if (iReadCnt > 0)        {            iReadTimes ++;     // 讀取次數加1            printf("ReadTimes is: %d, the RecordInfo is:\n", iReadTimes);        }        for (iRecCnt = 0; iRecCnt < iReadCnt; iRecCnt ++)   // 列印讀取到的記錄值        {            memset(szRecordInfo, 0x00, sizeof(szRecordInfo));            strncpy(szRecordInfo, szRecordSet[iRecCnt], sizeof(szRecordInfo)-1);            printf("%s\n", szRecordInfo);        }        if (iRetVal == 0)   // 表示檔案記錄已掃描完, 直接退出        {            break;        }    }    return 0; }/*********************************************************************** 功能描述:從檔案中讀取記錄內容* 輸入參數:fp-檔案指標     * 輸出參數:szRecordSet-記錄內容資訊集            piReadCnt-讀取到的條數* 返 回 值:1-下一輪繼續讀取  0-本輪已讀取完畢  -1-讀取失敗* 其它說明:無* 修改日期        版本號碼         修改人           修改內容* -------------------------------------------------------------------* 20150528        V1.0     Zhou Zhaoxiong        建立***********************************************************************/INT32 ReadRecordFromFile(FILE *fp, UINT8 szRecordSet[][MAX_RECORD_LEN], UINT32 *piReadCnt){    UINT8  szRecordInfo[MAX_RECORD_LEN] = {0};    // 儲存讀取到的每條記錄資訊    UINT32 iRecordLen                   = 0;      // 儲存讀取到的每條記錄資訊的長度    if (fp == NULL || piReadCnt == NULL)    {        printf("ReadRecordFromFile: input paramter(s) is NULL!\n");        return -1;    }    // 讀取檔案記錄    while ((!feof(fp)) && (!ferror(fp)))   // 遇到檔案結尾或讀取錯誤則退出    {        // 讀取一條記錄        memset(szRecordInfo, 0x00, sizeof(szRecordInfo));        fgets(szRecordInfo, sizeof(szRecordInfo)-1, fp);        // 去掉記錄後面的斷行符號分行符號        iRecordLen = strlen(szRecordInfo);        while (iRecordLen > 0)        {            if (szRecordInfo[iRecordLen-1] == '\n' || szRecordInfo[iRecordLen-1] == '\r')            {                szRecordInfo[iRecordLen-1] = '\0';            }            else            {                break;            }            iRecordLen --;        }        // 判斷是否為空白行, 是則繼續讀取        if (strlen(szRecordInfo) == 0)        {            continue;        }        // 將記錄資訊拷貝到輸出緩衝中        strncpy(szRecordSet[(*piReadCnt)++], szRecordInfo, MAX_RECORD_LEN-1);        // 如果超出最大條數限制, 則直接返回        if ((*piReadCnt) >= ONCE_READ_COUNT)        {            return 1;        }    }    return 0;}

四、程式說明
1.被讀取的檔案命名為“TestFile.txt”,存放在“/home/zhou/zhouzx/test/file/”目錄下。
2.為了方便看到效果,程式中設定每一次最大讀取條數為5,每條記錄的最大長度為50(最大長度值的設定的依據是讀取的檔案記錄的長度)。將讀取到的記錄存放到一個二維陣列變數中,其中第一維是每次讀取到的記錄條數,第二維是每條記錄的長度。
3.如果一輪未讀完資料,則檔案指標會自動跳到下一次讀取的記錄的開頭。結束一輪讀取的條件有三個:已達讀取上限、記錄已全部讀完、讀取錯誤。
4.如果檔案中出現了空行,那麼程式並不會將之作為有效行而使得讀取條數增加,而是從下一個非空行開始繼續計數。
5.程式會列印出讀取的次數及每次讀取到的具體記錄資訊,方便查看程式分批處理的執行情況。

五、程式編譯及運行結果
在Linux下,使用“gcc -g -o BatchReadFile BatchReadFile.c”命令對程式進行編譯,產生“BatchReadFile”。下面執行“BatchReadFile”命令來對程式進行測試。
1.“TestFile.txt”檔案中的內容如下:

100001100002100003100004

則程式運行結果為:

ReadTimes is: 1, the RecordInfo is:100001100002100003100004

2.“TestFile.txt”檔案中的內容如下:

100001100002100003100004100005

則程式運行結果為:

ReadTimes is: 1, the RecordInfo is:100001100002100003100004100005

3.“TestFile.txt”檔案中的內容如下:

100001100002100003100004100005100006

則程式運行結果為:

ReadTimes is: 1, the RecordInfo is:100001100002100003100004100005ReadTimes is: 2, the RecordInfo is:100006

4.“TestFile.txt”檔案中的內容如下:

100001100002100003100004100005100006100007100008100009100010100011

則程式運行結果為:

ReadTimes is: 1, the RecordInfo is:100001100002100003100004100005ReadTimes is: 2, the RecordInfo is:100006100007100008100009100010ReadTimes is: 3, the RecordInfo is:100011

可見,即使檔案中存在空行,程式也能夠正常處理。

六、總結
本文對分批讀取檔案中資料的程式流程進行了介紹,並給出了C程式實現。在實際的軟體開發項目中,每個檔案包含的記錄條數要多很多,但基本的程式編寫流程是一樣的。大家可以根據實際需要對本文中的程式進行修改來滿足具體的要求。

本人公眾號:zhouzxi,請掃描以下二維碼:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.