【问题标题】:Could someone tell me why copying a file like this doesn't work?有人能告诉我为什么复制这样的文件不起作用吗?
【发布时间】:2015-05-28 19:19:42
【问题描述】:

我正在尝试逐字节复制 exe 文件。我比较了 2 的十六进制文件,它们完全不同。似乎有些值没有被加载..

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

int main(){

    ifstream fin("file.exe", ifstream::binary);
    vector<char> buffer(1, 0);


    ofstream newfile;
    newfile.open("newfile.exe", ios::binary);

    while (fin.read(buffer.data(), buffer.size())){
        streamsize s = fin.gcount();
        for (int i = 0; i < buffer.size(); i++){
            if (buffer[i] != EOF){
                newfile << buffer[i];
                cout << buffer[i] << endl;
            } else {
                break;
            }

        }
    }
}

【问题讨论】:

  • 你需要streamsize s = fin.gcount() 语句吗?无论如何,你不会使用它的结果。
  • 该向量是为了以防我想开始一次抓取多个字节。我将其与 EOF 进行比较,因为到目前为止它已经奏效了。
  • 最明显的问题是buffer[i] != EOF。由于buffer[i] 包含一个字符而EOF 不是一个字符,所以这种比较没有意义。
  • @Jlegend:然而你在这里抱怨它不起作用工作......
  • 一个问题是文件流是一个 block 设备,这意味着它喜欢以大块的形式传输数据。我建议向量的最小大小为 512(常见的扇区大小)。

标签: c++ windows file copy


【解决方案1】:

为什么要读取和写入带有单个 char 的向量? s 的目的是什么?您为什么尝试使用 IOStreams 与 EOF 进行比较?这段代码似乎是 C 和 C++ 的奇怪混合,结果完全被破坏了!

我会这样做:

#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>

int main()
{
    std::ifstream fin ("file.exe",    std::ios::binary);
    std::ofstream fout("newfile.exe", std::ios::binary);

    std::copy(
       std::istream_iterator<char>(fin),
       std::istream_iterator<char>(),
       std::ostream_iterator<char>(fout)
    );
}

甚至只是:

#include <iostream>
#include <fstream>

int main()
{
    std::ifstream fin ("file.exe",    std::ios::binary);
    std::ofstream fout("newfile.exe", std::ios::binary);

    fout << fin.rdbuf();
}

别闹了,别大惊小怪!

这对于一般情况下的流非常有效,但是,if all you want to do is perform a byte-for-byte file copy, you'd get your OS to do it for you。它可以比你更快地做到这一点!例如,CopyFile 在 Windows 上。

【讨论】:

  • 或者更简单:newfile&lt;&lt;fin.rdbuff(); 一行。
  • @DavidHaim: 是的或者那个:) (rdbuf)
  • 我建议 OP 为此找到一个 OS API。操作系统应该已经测试了一些优化的文件复制功能。
【解决方案2】:

感谢您的所有帮助。这就是我最终完成工作的方式。

#include <iostream>     
#include <fstream>      
using namespace std;

int main() {
    ifstream is("file.exe", ios::binary);
    ofstream fs("newfile.exe", ios::binary);
    if (is) {
        is.seekg(0, is.end);
        int length = is.tellg();
        is.seekg(0, is.beg);

        char * buffer = new char[length];

        is.read(buffer, length);
        is.close();

        for (int i = 0; i < length; i++) {
            fs << buffer[i];
        }

        delete[] buffer;
    }
}

【讨论】:

    猜你喜欢
    • 2015-05-16
    • 2021-06-23
    • 2021-05-02
    • 1970-01-01
    • 2022-12-04
    • 1970-01-01
    • 2015-09-12
    • 2019-02-15
    • 1970-01-01
    相关资源
    最近更新 更多