C ++最强大的复制文件的方法

时间:2016-01-15 13:27:17

标签: c++ copy memory-efficient robustness robust

好的,所以我知道磁盘写入错误是非常罕见的,所以请仔细看看,因为我正在使用的数据非常重要(比如SSID很重要)。因此,我希望使用绝对最小的内存量以绝对最强大的方式复制文件。到目前为止,这是我所拥有的。它吸收了大量内存,但我找不到来源。它的工作方式是重新检查大量的时间,直到它得到确认的结果(它可能会大量增加错误的误报数量,但它可能会大幅降低实际错误的几率)。此外,底部的睡眠是您有时间使用Windows任务管理器分析程序的整体性能。


#include <cstdio>   // fopen, fclose, fread, fwrite, BUFSIZ
#include <cstdlib>
#include <unistd.h>
#include <iostream>

using namespace std;

__inline__ bool copy_file(const char* From, const char* To)
{
    FILE infile = (*fopen(From, "rb"));
    FILE outfile = (*fopen(To, "rwb+"));
    setvbuf( &infile, nullptr, _IONBF, 0);
    setvbuf( &outfile, nullptr, _IONBF, 0);

    fseek(&infile,0,SEEK_END);
    long int size = ftell(&infile);
    fseek(&infile,0,SEEK_SET);
    unsigned short error_amount;
    bool success;
    char c;
    char w;
    char l;

    for ( fpos_t i=0; (i != size); ++i ) {
        error_amount=0;
        fsetpos( &infile, &i );
        c = fgetc(&infile);
        fsetpos( &infile, &i );
        success=true;
        for ( l=0; (l != 126); ++l ) {
            fsetpos( &infile, &i );
            success = ( success == ( fgetc(&infile)==c ) );
        }
        while (success==false) {
            fsetpos( &infile, &i );
            if (error_amount==32767) {
                cerr << "There were 32768 failed attemps at accessing a part of the file! exiting the program...";
                return false;
            }
            ++error_amount;
            //cout << "an error has occured at position ";
            //printf("%d in the file.\n", (int)i);
            c = fgetc(&infile);
            fsetpos( &infile, &i );
            success=true;
            for ( l=0; (l != 126); ++l ) {
                fsetpos( &infile, &i );
                success = ( success == ( fgetc(&infile)==c ) );
            }
        }



        fsetpos( &infile, &i );
        fputc( c, &outfile);
        fsetpos( &outfile, &i );


        error_amount=0;
        w = fgetc(&infile);
        fsetpos( &outfile, &i );
        success=true;
        for ( l=0; (l != 126); ++l ) {
            fsetpos( &outfile, &i );
            success = ( success == ( fgetc(&outfile)==w ) );
        }
        while (success==false) {
            fsetpos( &outfile, &i );
            fputc( c, &outfile);
            if (error_amount==32767) {
                cerr << "There were 32768 failed attemps at writing to a part of the file! exiting the program...";
                return false;
            }
            ++error_amount;
            w = fgetc(&infile);
            fsetpos( &infile, &i );
            success=true;
            for ( l=0; (l != 126); ++l ) {
                fsetpos( &outfile, &i );
                success = ( success == ( fgetc(&outfile)==w ) );
            }
        }
        fsetpos( &infile, &i );
    }

    fclose(&infile);
    fclose(&outfile);

    return true;
}

int main( void )
{
    int CopyResult = copy_file("C:\\Users\\Admin\\Desktop\\example file.txt","C:\\Users\\Admin\\Desktop\\example copy.txt");

    std::cout << "Could it copy the file? " << CopyResult << '\n';

    sleep(65535);
    return 1;
}


那么,如果我的代码以最佳方式走在正确的轨道上,那么可以用我的代码来改进它?但是,如果我的代码完全没有最佳解决方案,那么最佳解决方案是什么?请注意,这个问题主要是为了检测非常非常非常(等)重要数据的应用中罕见的磁盘写入错误。

2 个答案:

答案 0 :(得分:2)

我只是复制文件而不进行任何特殊检查,最后我会读取文件并将其哈希值与预期值进行比较。对于哈希函数,我会使用MD5或SHA-1。

答案 1 :(得分:1)

#include <boost/filesystem.hpp>
#include <iostream>

int main()
{
    try
    {
        boost::filesystem::copy_file( "C:\\Users\\Admin\\Desktop\\example file.txt",
                                      "C:\\Users\\Admin\\Desktop\\example copy.txt" );
    }
    catch ( boost::filesystem::filesystem_error const & ex )
    {
        std::cerr << "Copy failed: " << ex.what();
    }
}

这将调用可用的最强大的实现 - 操作系统提供的实现 - 并报告任何失败。

我的观点是:

保存的数据最终损坏的可能性在天文数字上很小。

任何可能存在这个问题的应用都应该在冗余存储上运行,也就是RAID阵列,执行校验和的文件系统(如BtrfsZFS)等,再次降低失败的可能性显著

在本土I / O功能中执行复杂的操作,另一方面,会增加错误和/或错误否定的概率