2017-08-08 1 views
-2

私はlibcurlを使用して多数の電子メールファイルを取り出し、そのファイルをディスクに書き込み、領収書を生成するプログラムを書いています。成功が返されたにもかかわらずofstreamで書かれていないデータ

私の問題は、領収書のほとんどが書かれ得るように見える一方で、電子メールの大半はディスクに書き込まれていない、ということです。さらに悪いことに、ファイルが書き込まれなくても、ofstreamは成功を返します。そのため、ファイル書き込みが正常に完了しなかった場合でも領収書が書き込まれます。同時に可能で、書き込みのだけ一定数 -

私の推測では、ofstreamのが非同期であるため、書き込みが時間内に完了しない場合は、それが床に落ちますよ、ということです。私はちょうどここで推測しています。 おそらく、私のコードを同期的に書くためにリファクタリングする必要がありますが、それは必要であるとは思えません。どのように私はこの仕事をすることができます誰も考えているのですか?

メールサイズの範囲は、数KBから数MBです。

int write_file(string filename, string mail_item) { 
    ofstream out(filename.c_str()); 
    out << mail_item; 
    out.close(); 
    out.flush(); 
    if (!out) { 
     return FUNCTION_FAILED; 
    } 
    return FUNCTION_SUCCESS; 
} 

これは、他の機能の一部であり、この問題の唯一の顕著なコードが示されているように切り出されました。

vector<string> directory = curl_listroot(curl);  

for (int i=0; i<directory.size(); i++) { 
    vector<int> mail_list = curl_search(curl,directory[i],make_vector<string>() << "SEEN" << "RECENT" << "NEW" << "ANSWERED" << "FLAGGED"); 
    for (int j=0; j<mail_list.size(); j++) { 
     curl_reset(curl, imap.username, imap.password); 
     string mail_item = curl_fetch(curl,directory[i],mail_list[j]); 
     if (mail_item.compare("") != 0) { 
      string m_id = getMessageID(mail_item); 
      string filename = save_path+"/"+RECEIPTNAME+"/"+clean_filename(m_id) + ".eml"; 
      if (!file_exists(filename)) { 
       string real_filename; 
       real_filename = save_path+"/"+INBOXNAME+"/"+clean_filename(m_id) + ".eml"; 
       int success = write_file(real_filename, mail_item); 
       if (success == FUNCTION_SUCCESS) { 
        write_file(filename, ""); //write empty receipt 
       } 
      } 
     } 
    } 
} 

すべての提案はありがたく受け取りました!ありがとうございました!

+0

ストリームを開いた後、ストリームの状態を確認してみてください。あなたが書いた後。そして、あなたが終わった後。フラッシュする必要はありません(ストリームバッファは終了の一環としてフラッシュされます)ので、フラッシュ後に行う必要はありません。 –

+1

貼り付けたコードで何か問題があります.... 'int write_file(string filename、string mail_item){'は関数宣言で、 'for'ループの直後です。 –

+0

'out user0042

答えて

0

大丈夫です。私は答えを見つけました - 良い答えがあるかもしれませんが、これは私のために働きます。この問題はOSの中にあるようです(この場合はLinux) - ofstreamが完了し、OSにファイルを書き込む責任を負いましたが、ファイルは実際にはまだ書き込まれていません(したがって、ofstreamは同期している可能性がありますファイルからデータを安全にディスクに書き込むファイルへの書き込みを終了することはできません)。急速に連続して膨大な数の書き込み(潜在的には何千もの書き込み)があるとすれば、これは必ずしも機能しません。 OSは手を空に投げてフロアにかなりの数のファイルを書き込む可能性があります(したがって、ファイルを同期的に書き込むための元々の要求)。

解決方法私の解決方法は、各書き込みの後に一時停止して、OSが追いつく時間を与えることです。しかし、空でないファイルを書き込むのに0.5秒かかることはありません。さらに、低速ストレージでは、0.5秒で十分ではないかもしれません。私は自分のコードを改善するための賢明な提案を歓迎するでしょう。

int write_file(string filename, string mail_item) { 
    ofstream out(filename.c_str()); 
    if (!out) { 
     return FUNCTION_FAILED; 
    } 
    out << mail_item << endl; 
    out.flush(); 
    usleep(500000); //wait for half a second to give the OS time to output the file 
    if (!out) { 
     return FUNCTION_FAILED; 
    } 
    out.close(); 
    if (!out) { 
     return FUNCTION_FAILED; 
    } 
    return FUNCTION_SUCCESS; 
} 
関連する問題