emplace_back + ofstream + windows - > bug?

问题描述:

下面的代码尝试在./out文件夹中创建800个文件。在使用g ++ 4.9.2的Linux Debian上,该程序正常工作。但在具有g ++ 5.2.0(MinGW)的Windows 7或8上,程序停止在509个文件。该错误似乎是在类Task的构造函数中使用emplace_back和ofstream的组合。它是错误吗?emplace_back + ofstream + windows - > bug?

//g++ -std=c++11 main.cpp 
#include <sstream> 
#include <fstream> 
#include <list> 
#include <iostream> 

#ifdef _WIN32 
    #include <io.h> 
#else 
    #include <sys/stat.h> 
#endif 

using namespace std; 

int i; 

struct Task 
{ 
    ofstream out; 
    Task(string file_name): out(file_name) 
    { 
     if(!out) {cout<<i<<"\n"; exit(1);} 
    } 
}; 

int main() 
{  
    #ifdef _WIN32 
     string output_folder = ".\\out"; 
     mkdir(output_folder.c_str()); 
     output_folder+="\\"; 
    #else 
     string output_folder = "./out"; 
     mkdir(output_folder.c_str(),S_IRWXU); 
     output_folder+="/"; 
    #endif 

    list<Task> ltask; 
    for(i=0; i<800; i++) 
    { 
     ostringstream os; 
     os<<output_folder<<i; 
     ltask.emplace_back(os.str()); 
    } 
    return 0; 
} 
+0

如果您在Windows计算机上运行防病毒软件,我会关闭它并重试。这可能会阻止它创建太多文件。 – NathanOliver

+0

这是一个FAT16文件系统吗?在这种情况下[单个文件夹中的最大文件数为512](http://stackoverflow.com/a/14407078/5181033) –

正是在打开的文件(在Windows或运行时库或其他地方)的数量的限制... ...在代码更改周期上面用下面的代码会导致同样的结果:

list<ofstream*> l; 
for(i=0; i<800; i++) 
{ 
    ostringstream os; 
    os<<output_folder<<i; 
    l.push_back(new ofstream(os.str())); 
} 
for(auto p: l) delete p; 
+0

因此,如果他在写完文件后关闭了文件,他会好吗? –

+1

问题是同时打开文件的数量。在Windows中,每个进程不能超过512个。上面的“删除”示例显示emplace_back被怀疑是错误的。 – Sergey

+0

@谢谢你是对的,我删除了帖子。谢谢你的评论。 – shuva

请参阅this question

CRT(由C++标准库使用)默认情况下具有512个同时打开文件描述符的限制。你使用3作为stdin,stdout和stderr,它留下了509.(你的任务不仅仅是创建文件;它们保持打开状态。)

如果你在创建文件后关闭文件,你会没事的。您还可以提高限制(在其他问题中解释)或使用Windows文件句柄,其中有一个更高的限制。