我想多次复制可执行文件本身。
我尝试了以下代码:
#include <fstream>
#include <string>
int main() {
std::ifstream from("main.exe", std::ios::binary);
auto buf { from.rdbuf() };
for(int x { 0 }; x <= 10; ++x) {
std::string name { "main" + std::to_string(x) + ".exe" };
std::ofstream out(name, std::ios::binary);
out << buf;
out.close();
}
from.close();
return 0;
}
但是它没有按我的预期工作(它不会重复复制可执行文件。请参阅下面的屏幕截图中的大小列):
如何解决这个问题?
从输入文件流缓冲区读取会消耗数据。复制文件后,您需要将流重置为开始:
...
for (int x{ 0 }; x <= 10; ++x) {
std::string name{ "main" + std::to_string(x) + ".exe" };
std::ofstream out(name, std::ios::binary);
out << buf;
out.close();
from.seekg(0, std::ios::beg); // need to go back to the start here
}
...
您可以简单地使用
std::filesystem
标准库功能来实现此目的:
int main() {
std::filesystem::path input("main.exe");
for (int x{ 0 }; x <= 10; ++x) {
std::filesystem::path outfile("main" + std::to_string(x) + ".exe");
std::filesystem::copy_file(input, outfile, std::filesystem::copy_options::overwrite_existing);
}
return 0;
}
在第一次迭代期间从输入缓冲区读取所有内容后,输入缓冲区为空。因此,您的后续迭代也将呈现空副本。我建议将
from
缓冲区初始化移到循环内,如下所示:
#include <fstream>
#include <string>
int main() {
for (int x{ 0 }; x <= 10; ++x) {
std::ifstream from("main.exe", std::ios::binary);
auto buf{ from.rdbuf() };
std::string name{ "main" + std::to_string(x) + ".exe" };
std::ofstream out(name, std::ios::binary);
out << buf;
out.close();
from.close();
}
return 0;
}
在其他答案中,数据将从文件中多次读取(每次保存一次)。
如果您在循环内创建一个新的
std::ifstream
对象,就会发生这种情况,如果您使用 seekg
转到流的开头,也会发生这种情况。
由于磁盘访问相对较慢(与内存访问相比),因此将其一次读入内存,然后根据需要多次保存从内存中会更高效。 下面的代码将文件二进制内容读取到
std::vector
中。然后多次写入向量的内容以创建新文件:
#include <string>
#include <vector>
#include <fstream>
int main() {
// Read the entire main.exe file into memory:
const std::string inFilename{ "main.exe" };
std::ifstream inFile{ inFilename, std::ios_base::binary };
std::vector<char> inFileData{ std::istreambuf_iterator<char>(inFile), std::istreambuf_iterator<char>() };
inFile.close();
// Save it as many times as needed:
for (int x{ 0 }; x <= 10; ++x)
{
std::string name{ "main" + std::to_string(x) + ".exe" };
std::ofstream outFile{ name, std::ios::binary };
outFile.write(inFileData.data(), inFileData.size());
outFile.close();
}
}