2015-02-11 63 views
1

我需要用C編寫代碼,它可以讀取包含double值的大型數據矩陣的大型csv文件。我必須逐列閱讀,而且我沒有關於文件中行數和列數的事先信息。 什麼是以C語言處理它的最有效的方式 - 在時間和內存方面?我基本上需要分別處理每列,但如果讀取更有效,可以通過閱讀行來實現。最好的方式來讀取和處理大於0.5GB的數據文件C

如果之前詢問過,請直接回答問題。 謝謝

+3

如果我是你,我會考慮[內存映射文件](http://en.wikipedia.org/wiki/Memory-mapped_file)。 – ikh 2015-02-11 03:04:35

+0

這取決於您需要如何處理數據。如果你只需要對第n列進行求和或求平均值,比如說,不需要一次將整個文件讀入內存中,你可以一次讀取一行,並執行一次總計。 – 2015-02-11 10:42:00

回答

0

csv文件是一個文本文件。通常,每行由行尾字符分隔,逗號分隔列。您必須掃描每一行才能識別列。

有很多方法可以解決這個問題。你的解決方案真的取決於你習慣使用的例程。

我將使用malloc()分配一個儘可能大的緩衝區,使用fread()以塊讀取csv文件,並掃描它以查找和處理列。

#include <stdio.h> 
#include <stdint.h> 
#include <string.h> 
#include <malloc.h> 

// JFL 11 Feb 15 
int main(int argc,char *argv[]) 
{ 
    int r; 
    int allocsize,filesize,len; 
    char *fname; 
    char *alloc=0; 
    FILE *fh=0; 

    if(argc<2) 
     goto BAIL; 
    fname=argv[1]; 

    // open file, find size 
    if(!(fh=fopen(fname,"rb"))) 
     goto BAIL; 
    fseek(fh,0,SEEK_END); // seek to end 
    if((filesize=ftell(fh))<0) 
     goto BAIL; 
    fseek(fh,0,SEEK_SET); 

    // alloc buffer 
    allocsize=16*1024; // max buffer size 
    if(allocsize>filesize) 
     allocsize=filesize; // limit to filesize 

    // 'search' for the largest buffer we can use temporarily 
    for(;allocsize>1024;allocsize-=1024) 
    { 
     if((alloc=malloc(allocsize))) 
     break; // allocated 
    } // for 

    if(!alloc) 
    { // try once more, small buffer 
     allocsize=1024; 
     if(!(alloc=malloc(allocsize))) 
     goto BAIL; 
    } 

    // read the file 
    for(;filesize;) 
    { 
     len=filesize; // remaining size 
     if(len>allocsize) 
     len=allocsize; // limit to buffer size 
     if(len!=fread(alloc,1,len,fh)) // read 
     goto BAIL; 
     filesize-=len; // adjust remaining size 

     // process len bytes 
    } // for 

    r=ftell(fh); 

    printf("success, read %d bytes\n",r); 
BAIL: // common exit point 
    if(fh) 
     fclose(fh); // close if opened 
    if(alloc) 
     free(alloc); // free if allocated 
    return 0; 
} // main() 
+0

謝謝@Joe。有沒有辦法知道我可以承受多大的緩衝區?儘管我有16GB的RAM。 – Kaur 2015-02-11 07:10:47

+0

如何分配大尺寸緩衝區,系統逐頁讀取,例如4kb〜4096,所以表現明智,它仍然是一樣的。 – Sridhar 2015-02-11 16:49:41

0

爲CSV是基於行(線爲基礎的),你需要處理的列,最好的辦法是把整個文件在內存中:要求文件大小和allocagte的內存塊使用malloc。閱讀第一行並確定列數'numcols'。現在重新處理文件併爲每一行分配一個包含'numcols'條目的數組,這些條目將指向行中列的起始位置(因爲每個數字可以有不同的數字位數,所以您可能不會假定所有列的起始位置都相同在線中偏移)。現在您已準備好處理您的列。

如果文件不適合內存,您可以打開'numcols'附加輸出文件,將輸入行中的列寫入其中(例如,以二進制格式向文件寫入雙精度),然後倒回並處理每個包含列的文件。如果這些輸出文件適合內存,則可以將它們讀入一個數組中。 (我沒有說這是有效的。)

相關問題