मैं एक "fileUpdater" बनाने की कोशिश कर रहा हूं जो एक मूल फ़ाइल को एकाधिक निर्देशिकाओं में कॉपी करेगा, जहां एक ही नाम और एक्सटेंशन वाली फ़ाइल पहले मिली थी।

bool update_files(const string inputPath, const vector<string> outputPaths)
{
    ifstream src(inputPath);
    if(!src.is_open())
    {
        cout << "Unable to open input file\n" << inputPath <<endl;
        return false;
    }
    else
    {
        ofstream dst;
        for(unsigned int i=0; i<= outputPaths.size()-1; i++)
        {
            dst.open(outputPaths[i]);
            try
            {
                dst << src.rdbuf();
                dst.close();
            }
            catch(int e)
            {
                cout << "Unable to replace file\n" <<endl;
                cout << outputPaths[i] <<"\n"<< endl;
                cout << "Error code: " <<e<<endl;
            }
        }
    };
    src.close();
    return true;
}

निष्पादित करने के ठीक बाद

dst.open(outputPaths[i]);

दूसरे पुनरावृत्ति में, द्वारा खोली गई मूल फ़ाइल

ifstream src(inputPath);

मिटा दिया जाता है और शेष निर्देशिकाओं में केवल एक खाली फ़ाइल की प्रतिलिपि बनाई जाती है। मैंने भी कोशिश की

dst.clear();
dst.close();

तथा

src.clear();
src.seekg(0,ios::beg);

अगले पुनरावृत्ति में प्रवेश करने से पहले, लेकिन इससे कोई फर्क नहीं पड़ा।

अपडेट करें विभिन्न फाइलों को आजमाने के बाद, मुझे एहसास हुआ कि व्यवहार इनपुट फ़ाइल पर निर्भर करता है। उपरोक्त व्यवहार .m-files (MatLab) के लिए दिखाई दिया। .txt फाइलों के साथ इसका परीक्षण करने के बाद, सभी फाइलें मिटा दी गईं।

0
Veljko Lipovac 22 सितंबर 2018, 20:46

2 जवाब

सबसे बढ़िया उत्तर

प्रस्तावित विधियों में से कोई भी काम नहीं करता है। न तो पॉइंटर को रीसेट करना, न ही ifstream को लूप में खींचना, जिसके परिणामस्वरूप इनपुट फ़ाइल (जिसे बदलना नहीं है) को अक्सर अनावश्यक रूप से खोलना होगा।

यह अभी भी स्पष्ट नहीं है क्यों dst.open(outputPaths[i]); इनपुट फ़ाइल को मिटा रहा है। साथ ही वाइप का सटीक क्षण प्रयुक्त प्रकार की फाइलों पर निर्भर करता है।

मैंने निम्नलिखित वर्कअराउंड को लागू किया, प्रभावी रूप से इनपुट फ़ाइल को एक स्ट्रिंग में पढ़ा और इसे पहले से बंद कर दिया, ताकि इसे आगे पढ़ने/लिखने की कार्रवाई से बचाया जा सके।

bool update_files( const string inputPath, const vector<string> outputPaths)
{
    const char * in = inputPath.c_str();
    ifstream src(in);
    if(!src.is_open())
    {
        cout << "Unable to open input file\n" << inputPath <<endl;
        return false;
    }
    else
    {
        string buffer;
        streamsize s=src.gcount();
        src.seekg(0,ios::end);
        buffer.reserve(src.tellg());
        src.seekg(0,ios::beg);
        buffer.assign((istreambuf_iterator<char>(src)), istreambuf_iterator<char>());
        src.close();

        for(unsigned int i=0; i<= outputPaths.size()-1; i++)
        {
            const char * out = outputPaths[i].c_str();
            ofstream dst(out);
            try
            {
                dst << buffer;
                dst.close();
            }
            catch(int e)
            {
                cout << "Unable to replace file\n" <<endl;
                cout << outputPaths[i] <<"\n"<< endl;
                cout << "Error code: " <<e<<endl;
            }
        }
    };
    src.close();
    return true;
}
0
Veljko Lipovac 25 सितंबर 2018, 14:17

जिस तरह से आप फ़ाइल की प्रतिलिपि बना रहे हैं, dst << src.rdbuf(); के साथ, आपकी इनपुट फ़ाइल के अंत में वर्तमान फ़ाइल स्थिति छोड़ देगी। दूसरे पुनरावृत्ति पर, वही पढ़ा कुछ भी नहीं पढ़ेगा (फ़ाइल की एक खाली प्रति छोड़कर) क्योंकि आप पहले से ही इनपुट फ़ाइल के अंत में हैं।

समाधान यह है कि का उपयोग करके प्रत्येक पढ़ने से पहले इनपुट फ़ाइल की शुरुआत में वापस जाना है। seekg. आपको कुछ भी पढ़ने से पहले tellg पर कॉल करना चाहिए (फ़ाइल खोलने के ठीक बाद), फिर उस स्थिति की तलाश करें।

auto startpos = src.tellg();
ofstream dst;
// ...
src.seekg(startpos);
dst << src.rdbuf();
0
1201ProgramAlarm 22 सितंबर 2018, 21:04