windows 用C++将一个文件的内容复制到另一个文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3820483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:19:55  来源:igfitidea点击:

Copying contents of one file to another in C++

c++windowsfilecopy

提问by T J

I am using the following program to try to copy the contents of a file, src, to another, dest, in C++. The simplified code is given below:

我正在使用以下程序尝试将文件 src 的内容复制到 C++ 中的另一个 dest。简化代码如下:

#include <fstream>
using namespace std;
int main()
{
  fstream src("c:\tplat\test\secClassMf19.txt", fstream::binary);
  ofstream dest("c:\tplat\test\mf19b.txt", fstream::trunc|fstream::binary);
  dest << src.rdbuf();
  return 0;
}

When I built and executed the program using CODEBLOCKS ide with GCC Compiler in windows, a new file named "....mf19.txt" was created, but no data was copied into it, and filesize = 0kb. I am positive I have some data in "...secClassMf19.txt".

当我在 Windows 中使用带有 GCC 编译器的 CODEBLOCKS ide 构建并执行程序时,创建了一个名为“....mf19.txt”的新文件,但没有将数据复制到其中,并且文件大小 = 0kb。我很确定我在“...secClassMf19.txt”中有一些数据。

I experience the same problem when I compiled the same progeam in windows Visual C++ 2008.

当我在 Windows Visual C++ 2008 中编译相同的程序时,我遇到了同样的问题。

Can anyone please help explain why I am getting this unexpected behaviour, and more importantly, how to solve the problem?

任何人都可以帮助解释为什么我会出现这种意外行为,更重要的是,如何解决问题?

回答by sbi

You need to check whether opening the files actually succeeds before using those streams. Also, it never hurts to check if everything went right afterwards. Change your code to this and report back:

在使用这些流之前,您需要检查打开文件是否真的成功。此外,之后检查一切是否正常也没有什么坏处。将您的代码更改为此并报告:

int main()
{
    std::fstream src("c:\tplat\test\secClassMf19.txt", std::ios::binary);
    if(!src.good())
    {
        std::cerr << "error opening input file\n";
        std::exit(1);
    }
    std::ofstream dest("c:\tplat\test\mf19b.txt", std::ios::trunc|std::ios::binary);
    if(!dest.good())
    {
        std::cerr << "error opening output file\n";
        std::exit(2);
    }
    dest << src.rdbuf();
    if(!src.eof())
        std::cerr << "reading from file failed\n";
    if(!dst.good())
        std::cerr << "writing to file failed\n";
    return 0;
}

I bet you will report that one of the first two checks hits.

我敢打赌,您会报告前两个检查中的一个命中。

If opening the input file fails, try opening it using std::ios::in|std::ios::binaryinstead of just std::ios::binary.

如果打开输入文件失败,尝试利用开放std::ios::in|std::ios::binary而不是只std::ios::binary

回答by Vagaus

Do you have any reason to not use CopyFilefunction?

你有什么理由不使用CopyFile功能吗?

Best

最好的事物

回答by gavinb

As it is written, your srcinstance is a regular fstream, and you are not specifying an open mode for input. The simple solution is to make srcan instance of ifstream, and your code works. (Just by adding one byte!)

正如所写,您的src实例是常规 fstream,并且您没有为输入指定开放模式。简单的解决方案是创建src的实例ifstream,并且您的代码可以工作。(只需添加一个字节!)

If you had tested the input stream (as sbi suggests), you would have found that it was not opened correctly, which is why your destination file was of zero size. It was opened in write mode (since it was an ofstream) with the truncation option to make it zero, but writing the result of rdbuf()simply failed, with nothing written.

如果您测试了输入流(如 sbi 建议的那样),您会发现它没有正确打开,这就是为什么您的目标文件大小为零的原因。它以写入模式打开(因为它是ofstream),并带有截断选项使其为零,但写入的结果rdbuf()只是失败,没有写入任何内容。

Another thing to note is that while this works fine for small files, it would be very inefficient for large files. As is, you are reading the entire contents of the source file into memory, then writing it out again in one big block. This wastes a lot of memory. You are better off reading in chunks (say 1MB for example, a reasonable size for a disk cache) and writing a chunk at a time, with the last one being the remainder of the size. To determine the source's size, you can seek to the end and query the file offset, then you know how many bytes you are processing.

另一件需要注意的事情是,虽然这对小文件很有效,但对大文件来说效率很低。照原样,您正在将源文件的全部内容读入内存,然后在一个大块中再次将其写出。这会浪费很多内存。您最好分块读取(例如 1MB,磁盘缓存的合理大小)并一次写入一个块,最后一个是大小的剩余部分。要确定源的大小,您可以寻找到末尾并查询文件偏移量,然后您就知道正在处理多少字节。

And you will probably find your OS is even more efficient at copying files if you use the native APIs, but then it becomes less portable. You may want to look at the Boostfilesystem module for a portable solution.

如果您使用本机 API,您可能会发现您的操作系统在复制文件方面效率更高,但随后它变得不那么可移植。您可能需要查看Boost文件系统模块以获得可移植的解决方案。