C++:std::ofstream 方法 open() 在第二次迭代时擦除打开的 ifstream 文件

C++: std::ofstream method open() wipes open ifstream file on second iteration

本文关键字:擦除 文件 ifstream 迭代 方法 ofstream std open C++ 第二次      更新时间:2023-10-16

我正在尝试构建一个"fileUpdater",它将原始文件复制到多个目录中,其中以前可以找到具有相同名称和扩展名的文件。

bool update_files(const string inputPath, const vector<string> outputPaths)
{
ifstream src(inputPath);
if(!src.is_open())
{
cout << "Unable to open input filen" << 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 filen" <<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文件(MatLab(上。 使用.txt文件对其进行测试后,擦除了所有文件。

使用dst << src.rdbuf();复制文件的方式会将当前文件位置保留在输入文件的末尾。 在第二次迭代中,相同的读取不会读取任何内容(留下文件的空副本(,因为您已经位于输入文件的末尾。

解决方案是在每次读取之前使用seekg查找到输入文件的开头。 您应该在阅读任何内容之前(打开文件后立即(调用tellg,然后寻找该位置。

auto startpos = src.tellg();
ofstream dst;
// ...
src.seekg(startpos);
dst << src.rdbuf();

提出的方法都不起作用。 既不重置指针,也不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 filen" << 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 filen" <<endl;
cout << outputPaths[i] <<"n"<< endl;
cout << "Error code: " <<e<<endl;
}
}
};
src.close();
return true;
}