2017-08-08 70 views
-2

我正在编写一个程序,它使用libcurl获取大量电子邮件文件,然后将文件写入磁盘,然后生成收据。即使返回成功,数据也不能写入流中

我的问题是,尽管大部分收据似乎都被写入,但大部分电子邮件并未写入磁盘。更糟糕的是,即使文件没有写入,ofstream也会返回成功 - 所以即使写入文件没有成功完成,也会写入收据。

我的猜测是,因为流是异步的,如果一个写入没有及时完成,那么它将被放置在地板上 - 只有一定数量的写入可以同时进行。我只是在这里猜测。 也许我需要重构我的代码来同步编写 - 但我不能相信这是必要的。有没有人有任何想法我可以做这项工作?

电子邮件的大小范围从几个千字节到几个兆字节。

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 << mail_item;'之后立即加上'if(!out){''? – user0042

回答

0

好的。我找到了答案 - 可能会有更好的答案 - 但这个对我来说很有用。问题似乎出现在操作系统(在这种情况下为Linux) - 流完成后,将文件写入操作系统的责任交给了操作系统,但文件还没有真正写入(所以虽然流可能同步结束结束写入文件,从数据到安全写入磁盘的文件,不是)。鉴于我正在快速连续(可能有成千上万)的大量写入,这不一定会奏效。操作系统可能会把手放在空中,并在地板上放置大量的文件写入(因此我最初的请求是同步写入文件的方式 - 端到端)。

我的解决方案是在每次写入后暂停以使操作系统时间赶上。它虽然不雅,但并不像应该的那么高效 - 写一个空文件并不需要半秒。另外,在慢速存储上,半秒时间可能不够。我会欢迎任何有关如何改进我的代码的巧妙建议。

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; 
} 
相关问题