如何在 C++ 中复制可执行文件本身?

问题描述 投票:0回答:4

我想多次复制可执行文件本身。

我尝试了以下代码:

#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;
}

但是它没有按我的预期工作(它不会重复复制可执行文件。请参阅下面的屏幕截图中的大小列):

如何解决这个问题?

c++ fstream
4个回答
3
投票

从输入文件流缓冲区读取会消耗数据。复制文件后,您需要将流重置为开始:

...

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;
}

2
投票

在第一次迭代期间从输入缓冲区读取所有内容后,输入缓冲区为空。因此,您的后续迭代也将呈现空副本。我建议将

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;
}

这是您应该得到的:


1
投票

在其他答案中,数据将从文件中多次读取(每次保存一次)。
如果您在循环内创建一个新的

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();
    }
}



0
投票

© www.soinside.com 2019 - 2024. All rights reserved.