我需要用C編寫代碼,它可以讀取包含double
值的大型數據矩陣的大型csv文件。我必須逐列閱讀,而且我沒有關於文件中行數和列數的事先信息。 什麼是以C語言處理它的最有效的方式 - 在時間和內存方面?我基本上需要分別處理每列,但如果讀取更有效,可以通過閱讀行來實現。最好的方式來讀取和處理大於0.5GB的數據文件C
如果之前詢問過,請直接回答問題。 謝謝
我需要用C編寫代碼,它可以讀取包含double
值的大型數據矩陣的大型csv文件。我必須逐列閱讀,而且我沒有關於文件中行數和列數的事先信息。 什麼是以C語言處理它的最有效的方式 - 在時間和內存方面?我基本上需要分別處理每列,但如果讀取更有效,可以通過閱讀行來實現。最好的方式來讀取和處理大於0.5GB的數據文件C
如果之前詢問過,請直接回答問題。 謝謝
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()
爲CSV是基於行(線爲基礎的),你需要處理的列,最好的辦法是把整個文件在內存中:要求文件大小和allocagte的內存塊使用malloc。閱讀第一行並確定列數'numcols'。現在重新處理文件併爲每一行分配一個包含'numcols'條目的數組,這些條目將指向行中列的起始位置(因爲每個數字可以有不同的數字位數,所以您可能不會假定所有列的起始位置都相同在線中偏移)。現在您已準備好處理您的列。
如果文件不適合內存,您可以打開'numcols'附加輸出文件,將輸入行中的列寫入其中(例如,以二進制格式向文件寫入雙精度),然後倒回並處理每個包含列的文件。如果這些輸出文件適合內存,則可以將它們讀入一個數組中。 (我沒有說這是有效的。)
如果我是你,我會考慮[內存映射文件](http://en.wikipedia.org/wiki/Memory-mapped_file)。 – ikh 2015-02-11 03:04:35
這取決於您需要如何處理數據。如果你只需要對第n列進行求和或求平均值,比如說,不需要一次將整個文件讀入內存中,你可以一次讀取一行,並執行一次總計。 – 2015-02-11 10:42:00