2012-10-07 50 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

相关问题