2011-10-15 67 views
0

我想将文件的所有内容读取到字符串或其他方法中,以允许我比较两个文件。我正在查找完全匹配的文件。如何在C++中将文件的内容读入字符串

只是我如何打开文件并阅读它有多少个字符的一小段。我用它来比较其他文件来检查是否有必要比较整个内容。

有没有一种方法可以比较两个缓冲区?

char buf[1000]; 
string str; 
ssize_t numread; 

    cout<<"Enter in the full file path: "; 

    getline(cin,str); 

    int f1= open(str.c_str(), O_RDONLY); 

     if(f1 ==-1){ 
      cout<<"file did not open"<<'\t'<<errno<<str<<endl; 
     } 

    int size= tell(f1); 
    lseek(f1,0,SEEK_SET); 
    numread= read(f1,buf,size); 

     if(numread==-1){ 
      cout<<errno<<endl; 
     } 

    cout<<'\t'<<":"<<str<<" #Chars:"<<numread<<endl; 

    close(f1); 
+0

如果我理解正确,您的最终目标是根据其内容比较一堆文件。如果是这种情况,您可能需要比较文件的摘要而不是内容,以查看它们是否匹配。 –

+0

@Eugen,要产生一个摘要,整个文件必须被读取,不妨比较读取时......只有这样才会更快,如果你比较一个文件agaist很多,可以重用摘要。 –

+0

@Evan:当我说:“根据他们的内容比较一堆文件”时,这就是我所指的。 –

回答

2

为此使用内存映射文件。 使用UNIX mmap()使用Windows MapViewOfFile()。 这会给你一个映射到文件内容的内存指针。 为什么这是一个好主意? 您不需要为使用malloc()或new()的文件分配空间。 这些文件可以是任何大小,确定32位限制,但应该有一个64位版本。 可以使用

memcmp(文件1,文件2,sizeoffile1)

享受...

编辑比较文件 - 添加了一些代码,用C

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

int 
cmpfile(char *file1, char *file2) 
{ 
    int result = -1; 
    int fd1, fd2; 
    off_t size1, size2; 
    char *ptr1, *ptr2; 

    fd1 = open(file1, O_RDONLY); 
    if (fd1 == -1) { 
    fprintf(stderr, "Failed to open file '%s' - %s\n", file1, strerror(errno)); 
    goto error1; 
    } 

    fd2 = open(file2, O_RDONLY); 
    if (fd2 == -1) { 
    fprintf(stderr, "Failed to open file '%s' - %s\n", file2, strerror(errno)); 
    goto error2; 
    } 

    size1 = lseek(fd1, 0, SEEK_END); 
    if (size1 == (off_t)-1) { 
    fprintf(stderr, "Failed to seek to end of file '%s' - %s\n", file1, strerror(errno)); 
    goto error3; 
    } 

    size2 = lseek(fd2, 0, SEEK_END); 
    if (size2 == (off_t)-1) { 
    fprintf(stderr, "Failed to seek to end of file '%s' - %s\n", file2, strerror(errno)); 
    goto error4; 
    } 

    if (size1 != size2) { 
    fprintf(stderr, "File sizes mimatched\n"); 
    goto error5; 
    } 

    ptr1 = mmap((void *)0, size1, PROT_READ, MAP_SHARED, fd1, 0); 
    if (ptr1 == MAP_FAILED) { 
    fprintf(stderr, "Failed to map file '%s' - %s\n", file1, strerror(errno)); 
    goto error6; 
    } 

    ptr2 = mmap((void *)0, size2, PROT_READ, MAP_SHARED, fd2, 0); 
    if (ptr2 == MAP_FAILED) { 
    fprintf(stderr, "Failed to map file '%s' - %s\n", file2, strerror(errno)); 
    goto error7; 
    } 

    if (memcmp(ptr1, ptr2, size1) == 0) { 
    result = 0; 
    } 

    munmap(ptr2, size2); 
error7: 
    munmap(ptr1, size1); 
error6: 
error5: 
error4: 
error3: 
    close(fd2); 
error2: 
    close(fd1); 
error1: 

    return result; 
} 

int main(int argc, char **argv) 
{ 
    int result = -1; 

    if (argc == 3) { 
    result = cmpfile(argv[1], argv[2]); 
    if (result == 0) { 
     printf("Files match\n"); 
    } else { 
     printf("Files don't match\n"); 
    } 

    } else { 
    fprintf(stderr, "Usage: %s <file1> <file2>\n", argv[0]); 
    } 

    return result; 
} 
+0

谢谢,我创建了一个编译错误,说memcmp没有在这个范围内声明..我有这样的函数内:void dir_traverse(const std :: string&path,std :: ostream&out),并使用它像这样int n; \t \t \t \t \t \t n = memcmp(buf1,buf2,numread); – user975044

+0

没关系:丢失包括:) – user975044

+0

很好的使用goto语句。如果你想在C++中做到这一点,你应该使用fstreams和迭代器。 Boost.Spirit有一个file_iterator类型,可以抽象出乱七八糟的C内存映射样板文件,并且具有跨平台的好处。 – gred

1

你可以使用一个istreambuf_iterator ,在cplusplus.com上为this example

#include <iostream> 
#include <iterator> 
#include <string> 
#include <stdexcept> 
#include <fstream> 

int main (int ac, char **av) { 
    if(ac != 3) 
    throw(std::runtime_error("Usage: progname file1 file2")); 

    if(std::equal(
     std::istreambuf_iterator<char>(
     std::ifstream(av[1], std::ios::binary).rdbuf()), 
     std::istreambuf_iterator<char>(), 
     std::istreambuf_iterator<char>(
     std::ifstream(av[2], std::ios::binary).rdbuf()))) { 
    std::cout << "same\n"; 
    return 0; 
    } else { 
    std::cout << "different\n"; 
    return 1; 
    } 
} 
相关问题