2011-10-15 72 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; 
    } 
} 
相關問題