2012-08-09 64 views
4

說我有文本文件My.txt文件這樣如何從Objective-C的大型文本文件讀取特定行?

this is line 1 
this is line 2 
.... 
this is line 999999 
this is line 1000000 

在Unix中,我可以通過發出命令,如「頭-1000 My.txt文件|尾-1」獲得的「這是行1000」的路線。在Objective-C中獲得這個的相應方法是什麼?

+0

您是否找到了答案? – ilan 2016-04-17 05:27:50

回答

1

最簡單的方法是使用NSString文件方法之一加載文件,然後使用 - [NSString componentsSeparatedByString:]方法獲取每行的數組。

或者您可以使用NSScanner,掃描換行符/回車字符來計算它們,直到找到您感興趣的行。

如果你真的關心內存使用情況,你可以看看NSInputStream使用它來讀取文件,保持新行數的計數。 NSScanner不能與NSInputStream一起工作令人遺憾。

+0

多數民衆贊成在一個瘋狂的建議 – 2012-08-09 01:22:15

+0

這是瘋狂的,我試圖給予答案從最簡單到最有效的 – 2012-08-09 04:08:14

+0

該花花公子問如何做隨機存取文件操作和所有這個地方不得不說是加載文件到數組中。荒謬。我不會爲他閱讀蘋果文檔。 – 2012-08-09 04:11:39

3

如果不是效率太低,有在內存中的整個事情一次,然後調用(我已經擴展到多行簡單的論述)的最緊湊的順序將是:

NSError *error = nil; 
NSString *sourceString = [NSString stringWithContentsOfFile:@"..." 
            encoding:NSUTF8StringEncoding error:&error]; 
NSArray *lines = [sourceString componentsSeparatedByCharactersInSet: 
            [NSCharacterSet newlineCharacterSet]]; 

NSString *relevantLine = [lines objectAtIndex:1000]; 

你應該檢查error的值和linescount進行驗證。

編輯:與Nathan的答案相比,在字符集中字符分割的好處在於,您將接受任何可能分隔換行符的任意五個Unicode字符,以及其中幾個字符位於其中的任何位置其他計數爲只有一箇中斷(例如按照\r\n)。

NSInputStream可能是你將不得不處理的內存足跡是一個問題,它比C的stdio.h fopen/fread/etc更難演化,所以你將不得不自己寫自己的一點點循環衝破。

1

我不認爲這是一個確切的重複,因爲它聽起來像你想跳過文件中的某些行,但你可以很容易地使用像一個在這裏的做法:

Objective-C: Reading a file line by line(有Specific answer一些示例代碼)

循環輸入文件,讀取一塊數據,然後查找換行符。對它們進行計數,當你輸入正確的數字時,輸出數據後直到下一個數據。

你的例子看起來像你可能有成千上萬的行,所以絕對不要只讀文件到NSString中,並且絕對不要將它轉換爲NSArray。

如果你想要這樣做的話,NSInputStream方式(在字符集解碼中有一些關鍵的優勢),這裏有一個很好的例子,它顯示了輪詢從流源中消耗所有數據的基本思想一個文件的例子,它有點矯枉過正)。它的輸出,但這個想法是好的輸入太: Polling versus Run Loop Scheduling

0

答案沒有解釋如何讀取文件過大保留在內存中。 Objective-C中沒有很好的解決方案來讀取大文本文件而不將它們放入內存中(這不總是一種選擇)。

在這種情況下,我想用C方法:

FILE* file = fopen("path to my file", "r"); 

size_t length; 
char *cLine = fgetln(file,&length); 

while (length>0) { 
    char str[length+1]; 
    strncpy(str, cLine, length); 
    str[length] = '\0'; 

    NSString *line = [NSString stringWithFormat:@"%s",str];   
    % Do what you want here. 

    cLine = fgetln(file,&length); 
} 

注意fgetln不會讓你的換行符。此外,我們+1的長度,因爲我們想爲NULL終止空間。