2011-08-24 33 views
8

我讀6000的文本文件加載到內存在一個循環下面的代碼打開了太多文件:C:使用執行opendir和開放

void readDocs(const char *dir, char **array){ 
DIR *dp = opendir(dir);; 
struct dirent *ep; 
struct stat st; 
static uint count = 0; 
if (dp != NULL){ 
    while (ep = readdir(dp)){ // crawl through directory 
    char name[strlen(dir) + strlen(ep->d_name) + 2]; 
    sprintf(name, "%s/%s", dir, ep->d_name); 

    if(ep->d_type == DT_REG){ // regular file 
     stat(name, &st); 
     array[count] = (char*) malloc(st.st_size); 
     int f; 
     if((f = open(name, O_RDONLY)) < 0) perror("open: "); 
     read(f, array[count], st.st_size)); 
     if(close(f) < 0) perror("close: "); 
     ++count; 
    }  

    else if(ep->d_type == DT_DIR && strcmp(ep->d_name, "..") && strcmp(ep->d_name, ".")) 
     // go recursive through sub directories 
     readDocs(name, array); 
    } 
} 
} 

在迭代2826我得到一個「打開的文件太多「打開第2826個文件時出現錯誤。 直到此時在關閉操作中沒有發生錯誤。
因爲它始終掛在第2826次迭代我不相信我應該等到一個文件被調用後真的關閉close();
我有使用fopen,fread和fclose相同的問題。
我不認爲它與這個片段的上下文有關,但如果你這樣做,我會提供它。
感謝您的時間!

編輯:
我把程序睡覺和檢查/ proc/fd /(感謝nos)。就像你懷疑有1024個文件描述符,我發現它是一個通常的限制。
+我給你了從目錄和所有子目錄中讀取文件的整個功能
+該程序在Linux上運行!對不起,忘了!

+6

某處,你沒有關閉()'d文件,也許在錯誤路徑上。如果這是在Linux上,看一下/ proc//fd /,你將至少看到哪個文件描述符你沒有關閉() – nos

+3

當然,顯示更多代碼:-) – cnicutar

+0

就好像系統實際上正在關閉調用close()之後的文件。你在哪個系統下運行這個程序? – Shlublu

回答

12

你需要在循環後調用closedir()。打開一個目錄也會消耗一個文件描述符。

+0

就是這樣。這將使遞歸有​​點複雜,但謝謝大家! – Callahan

+2

怎麼回事?只需在while循環結束後添加closedir(dp)即可。或者你有1000級的目錄?您也可以遞歸地列出所有文件,然後在遞歸之外逐個打開它們。 –

2

您可能正在觸及操作系統對允許的打開文件數限制。不知道你正在使用哪個操作系統,你應該谷歌你的操作系統+「打開的文件太多」,以找出如何解決這個問題。這裏是linux的一個結果,http://lj4newbies.blogspot.com/2007/04/too-many-open-files.html

+1

增加操作系統上打開文件的限制是錯誤的方法。他應該檢查他爲什麼不關閉他的文件。 – RedX

+0

檢查文件限制是否正確,這是硬限制 – ajreal

1

我加入解決了這個問題/etc/security/limits.conf

* soft nofile 40960

* hard nofile 102400

問題是,當登錄Debian的它顯示ulimit -n 40960,但是當蘇用戶,它再次1024。 需要對/etc/pam.d/su

session required pam_limits.so

取消註釋一行然後總是需要限制

0

,你應該調用closedir(),因爲它也執行opendir返回描述 在linux系統最大時間的/ proc這個數量多/ sys/fs/file-max文件可以打開 雖然你可以增加/減少這個數字