2012-10-07 48 views
4

如何檢查一個文件是否與使用Unix C的其他文件相同(具有相同的內容)?我的意思是,當我不能使用fopen, fread, fclose而只是open, read, close?我感興趣的答案,它展示瞭如何做到這一點只有在Unix的C.如何檢查Unix C中的文件是否相同?

我寫了一個程序,將文件複製到另一個,但不知道如何檢查,如果它們是相同的:/:

#include <stdio.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <stdlib.h> 

int main(int argc, char **argv) 
{ 
    const char *in_filename = "in.txt", *out_filename = "out.txt"; 
    int in_fd, out_fd, bytes_read, bytes_written; 
    int buffsize = 512; 
    char buffer[512]; 
    int success = 0; 

    in_fd = open(in_filename, O_RDONLY); 
    if (in_fd == -1) 
     return -1; 
    out_fd = open(out_filename, O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR); 
    if (out_fd == -1) 
     return -1; 

    for(;;) 
    { 
     bytes_read = read(in_fd, buffer, buffsize); 
     if (bytes_read > 0) 
     { 
      bytes_written = write(out_fd, buffer, bytes_read); 
      if(bytes_written < 0) 
       return -1; 
     } 
     else 
     { 
      if (bytes_read == 0) 
      { 
       if (close(in_fd) < 0) 
        return -1; 
       if (close(out_fd) < 0) 
        return -1; 
       success = 1; 
       break; 
      } 
      else if (bytes_read == -1) 
      { 
       break; 
       return -1; 
      } 
     } 
    } 

    if(success) 
     fprintf(stdout, "%s", "Success!\n"); 

    return 0; 
} 

繼承人是我的嘗試:

#include <stdio.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <stdlib.h> 

int main(int argc, char **argv) 
{ 
    const char *in_filename = "in.txt", *out_filename = "out.txt"; 
    int in_fd, out_fd, bytes_read_in, bytes_read_out; 
    int buffsize = 512; 
    char in_buffer[512], out_buffer[512]; 
    int the_same = 0; 

    in_fd = open(in_filename, O_RDONLY); 
    if (in_fd == -1) 
     return -1; 
    out_fd = open(out_filename, O_RDONLY); 
    if (out_fd == -1) 
     return -1; 

    for(;;) 
    { 
     bytes_read_in = read(in_fd, in_buffer, buffsize); 
     if (bytes_read_in > 0) 
     { 
      bytes_read_out = read(out_fd, out_buffer, buffsize); 
      if(bytes_read_out > 0) 
      { 
       int i = 0; 
       for(i=0; i<buffsize; i++) 
       { 
        if(in_buffer[i] != out_buffer[i]) 
         the_same = 0; 
       } 
       the_same = 1; 
      } 
     } 
     else 
     { 
      if (bytes_read_in == 0) 
      { 
       if (close(in_fd) < 0) 
        return -1; 
       if (close(out_fd) < 0) 
        return -1; 
       break; 
      } 
      else if (bytes_read_in == -1) 
      { 
       break; 
       return -1; 
      } 
     } 
    } 

    if(the_same) 
     fprintf(stdout, "%s", "Files are the same!\n"); 

    return 0; 
} 

但它表明文件是相同的,而對方不:(

+2

你有沒有嘗試過某些東西並卡住了某個地方? – Rohan

+0

@Rohan:yup我寫了一個程序,將一個文件複製到另一個文件,但不知道如何檢查它們是否相同:/ – Katie

+0

檢查文件的大小相同,然後打開這兩個文件並逐字節比較。 –

回答

3

你只需要在同一時間讀兩個緩衝區。舉例來說(也認爲處理錯誤),不使用C標準庫都:

#include <fcntl.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 

#define BUFFER_SIZE 1024 

static int 
bufcmp(const void *p, const void *q, size_t n) 
{ 
    const char *p1 = p; 
    const char *p2 = q; 

    while (n-- > 0) { 
     if (*p1++ != *p2++) 
      return 0; 
    } 

    return 1; 
} 

int 
main(int argc, char *argv[]) 
{ 
    int fd1 = open(argv[1], O_RDONLY); 
    int fd2 = open(argv[2], O_RDONLY); 
    int same = 1; 

    for (;;) { 
     char buf1[BUFFER_SIZE], buf2[BUFFER_SIZE]; 
     ssize_t n1 = read(fd1, buf1, BUFFER_SIZE); 
     ssize_t n2 = read(fd2, buf2, BUFFER_SIZE); 

     if (n1 < n2) { 
      same = 0; 
      break; 
     } else if (n1 == 0) { 
      break; 
     } else if (bufcmp(buf1, buf2, n1) == 0) { 
      same = 0; 
      break; 
     } 
    } 

    if (same) 
     write(STDOUT_FILENO, "Same content.\n", 14); 

    close(fd1); 
    close(fd2);  

    return 0; 
} 

NB(感謝user4815162342):此代碼是不是完全正確的。事實上,如果由read返回的讀取的字節數小於請求的字節數,則不是錯誤。但是,爲了縮短這個代碼,我沒有包含這個管理。

+0

geez,你的編輯正是我需要的!謝謝:) – Katie

+2

This code是錯誤的:不能保證兩個'read'的調用都會一次返回所有請求的數據。 'read'可以返回比請求更少的數據。 – user4815162342

+1

請考慮修改發佈的代碼,以防兩次調用read'返回相同文件的不同大小,或者至少提到這個問題。您的答案被接受,所以未來的用戶會找到它並引用它包含的代碼。 – user4815162342

1

什麼是與問題使用兩個緩衝區,每個文件一個,每個文件讀取相同的字節數,然後將緩衝區內容與memcmp進行比較?

+0

是在unix內核中定義的'memcmp'?如果沒有,我不能使用它:( – Katie

+0

無論如何,你可以寫你自己的... – md5

+0

使用memcmp沒有問題,它是C標準,但你可以有一個大文件分配足夠的內存的問題 – user411313

相關問題