2014-11-14 59 views
0

我試圖讀取一個文件與1024行,每行9次相同的字母和返回,如果它發現一行不符合這個條款。C函數讀取(文件,緩衝區,字節讀取)打破一個字符串

的文件是如下但1024線:

eeeeeeeee 
eeeeeeeee 
eeeeeeeee 

代碼:

fd = open(fileName, O_RDONLY); 
lseek(fd,0,SEEK_SET); 


if(flock(fd, LOCK_SH) == -1) 
     perror("error on file lock"); 

if(fd != 0){ 

    read(fd, lineFromFile, (sizeof(char)*10)); 
    arguments->charRead = lineFromFile[0]; 

    for(i=0; i < 1024; i++){   
     var = read(fd, toReadFromFile, (sizeof(char)*10)); 
     if(strncmp(toReadFromFile,lineFromFile,10) != 0 || var < 10){   

      arguments->result = -1; 
      printf("%s \n\n",toReadFromFile); 
      printf("%s \n",lineFromFile); 
      printf("i %d var %d \n",i,var);     
      free(toReadFromFile); 
      free(lineFromFile); 
      return ; 
     }      
    } 
} 

輸出:

> eeeee 
eeee 

eeeee 
eeee 
i 954 var 6 

我有5個不同的文件和不同的字母,每個單獨的文件在這個特定的行(954)中給出了這個輸出,並且該行對於最後用\ n書寫了9次的字母是正確的。

任何想法,爲什麼會發生這種情況?如果我不使用lseek它可以正常工作,但我需要lseek將文件分成若干部分,以便通過不同的線程進行測試。我把lseek中的0索引簡化爲向你們展示。

謝謝。

+0

如果你正在嘗試使用'與fgets(讀取由行的文本文件行倒不如讓庫函數做的工作適合你)'或'fscanf()'。而不是使用'fseek()',每個線程可以在它感興趣的人之前簡單地丟棄任何行。另一條路線可以是將整個10k文件(它不是很大,並且你知道它的大小)讀入所有可用的靜態存儲器線程,讓他們都檢查相同的副本。 – 2014-11-14 18:18:42

+0

當您從中讀取文件時,您的其他線程之一是否正在對您的文件執行lseek?你應該把'lseek'移到你鎖定文件的地方。這樣,一旦你鎖定了,你就只能'查看'。 – JS1 2014-11-14 18:20:20

+0

問題是,由於我已經有了使用線程讀取整個文件的其他程序,因此這個新程序需要共享相同的文件才能更快地進行測試,而且我的老師說它必須使用lseek()和read()。我不明白它是如何工作的大部分線路,只是在特定的路線失敗。沒有意義。 – 2014-11-14 18:27:10

回答

1

它看起來像你正在尋找"eeeee\neeee",而不是"eeeeeeeee\n"。這意味着你的文件應該應該這樣開始:

eeeee 
eeeeeeeee 
eeeeeeeee 

,並最終像這樣:

eeeeeeeee 
eeee 

如果你的文件結尾是這樣的:

eeeeeeeee 
eeeeeeeee 

然後,當你到了最後行,它將失敗,因爲您只會閱讀"eeeee\n"而不是"eeeee\neeee"

鑑於您評論中的新信息,我認爲問題在於您不應該尋找到行的中間位置(本例中爲342和684)。你應該尋求預期的字符串的偶數倍(如340和680)。另外,第954行不是發生問題的地方。它應該是954 + X行,其中X是你尋找的行。

+0

但它在954行失敗,最後一行是1024.如果我使用3個線程與以下lseeks:lseek(fd,0,SEEk_SET)lseek(fd,342,SEEk_SET)lseek(fd,684,SEEk_SET) - 前兩個是成功的,最後一個失敗的是第954行。 如果它開始於eeeee,它不應該失敗的前2個線程?或者只在1024行失敗? – 2014-11-14 18:50:27

+1

有趣。你爲什麼尋求342和684?你不應該尋求可以被10整除的補償嗎?另外,您不應該在文件中查看第954行。您應該查看X + 954行,其中X是您尋找的行。在你的情況下,你找到68行的中間,所以問題發生在68 + 954 = 1022行,或者1023,如果第一行是第一行。 – JS1 2014-11-14 18:55:40

+0

你是對的:DI改變了並保存了從lseek像這樣: 'newIndex = lseek(fd,arguments-> startLineIndex * 10,SEEK_SET);''for(i = newIndex/10; i < arguments-> finishLineIndex; i ++)'謝謝 – 2014-11-14 19:12:51

1

無論你的程序有什麼其他問題,它肯定有這樣的:read()函數不保證讀取請求的全部字節數。除非遇到錯誤或文件末尾,否則它將讀取至少一個文件,並且在很多情況下它會讀取請求的全部字節數,但即使在文件結尾之前剩餘的字節數足夠多,也可以讀取read()更少的字節比請求。

催促您使用更高級別功能的註釋已被充分考慮,但如果您出於某種原因有義務使用read(),則必須注意讀取的字節數少於請求數的情況,並通過閱讀額外的字節到緩衝區未使用的尾端。可能多次。

在函數形式,可能看起來像這樣的:

int read_all(int fd, char buf[], int num_to_read) { 
    int total_read = 0; 
    int n_read = 0; 

    while (total_read < num_to_read) { 
     n_read = read(fd, buf + total_read, num_to_read - total_read); 
     if (n_read > 0) { 
      total_read += n_read; 
     } else { 
      break; 
     } 
    } 

    return (n_read < 0) ? n_read : total_read; 
} 
+0

已經解決了,不過謝謝。我真的需要使用lseek來做這個。 – 2014-11-14 19:17:44

+0

您可能確實需要使用'lseek()',但這並不意味着您不需要執行我所描述的操作。即使你的計劃到目前爲止沒有給你預期的結果,依靠它總是這樣做是不安全的。 – 2014-11-14 19:30:47