【C++】如何高效复制文件

如何高效复制文件

0. 缓冲区对效率的影响

  缓冲区的大小对效率的影响是巨大的。频繁的对文件进行操作会大大减缓速度,因此,如果使用单字符方式(如一边get单字符一边put单字符)进行读写将会非常缓慢。需要设置合理的缓冲区大小,才能提高读写效率。
  当然,缓冲区也不是越大越好(这些可能涉及到硬件层面)。可以把复制文件理解为搬家:一次多搬些东西(缓冲区大)一定比一次少搬些东西(缓冲区小)快。但是你的力气是有限的,一次搬的东西不能太多(缓冲区不是越大越好)。常用的缓冲区大小有 64kb、128kb等等(可以多测试几个缓冲区大小并选取最快的)

1. C方式:fread/fwrite

  这两个函数是C方式的文件操作函数,在头文件 <stdio.h> 中。C++方式下也可以使用。下面为参考代码:
  关键:注意缓冲区大小。本代码中设为1M。

int file_xcopy_stod(const char* source_dir, const char* destination_dir)
{
	 FILE* infile = fopen(source_dir, "rb");//二进制形式打开
	 if (infile == NULL) {//出错处理
   		 cout << "文件" << source_dir << "打开失败" << endl;
     		 return -1;
	 }
	  FILE* outfile = fopen(destination_dir, "wb");//二进制形式打开
	 if (outfile == NULL) {//出错处理
		  cout << "文件" << destination_dir << "打开失败" << endl;
		  fclose(infile);//记得关闭
		  return -1;
	 }
	  //开始读写
	 const int FLUSH_NUM = 1024 * 1024;//缓冲区大小设置为1M
	 char* ch = new(nothrow)char[FLUSH_NUM];
	 if (ch == NULL) {//出错处理
		  cout << "动态申请内存失败" << endl;
		  fclose(infile);//记得关闭
		  fclose(outfile);//记得关闭
		  return -1;
	 }
	  int ret; //按块读写
	 while (!feof(infile)) {
		  ret = fread(ch, 1, FLUSH_NUM, infile);
		  fwrite(ch, 1, ret, outfile); //写入成功读入的块数
	 }
	  delete[]ch;//记得释放
	 fclose(infile);//记得关闭
	 fclose(outfile);//记得关闭
	 return 0;
} 

2. C++方式:成员函数read/write

  头文件为 < fstream> 。下面为参考代码:
  关键:注意缓冲区大小。本代码中设为1M。

int file_xcopy_stod(const char* source_dir, const char* destination_dir)
{
  	 ifstream infile(source_dir, ios::in | ios::binary);//二进制形式打开
	 if (infile.is_open() == 0) {//出错处理
		 cout << "文件" << source_dir << "打开失败" << endl;
		 return -1;
	 }	
  	ofstream outfile(destination_dir, ios::out | ios::binary);//二进制形式打开
	 if (outfile.is_open() == 0) {//出错处理
	 	 cout << "文件" << destination_dir << "打开失败" << endl;
		  infile.close();//记得关闭
 		 return -1;
	 }
	  //开始读写
	 const int FLUSH_NUM = 1024 * 1024;//缓冲区大小设置为1M
	 char* ch = new(nothrow)char[FLUSH_NUM];
	 if (ch == NULL) {//出错处理
		  cout << "动态申请内存失败" << endl;
		  infile.close();//记得关闭
 		 outfile.close();//记得关闭
 		 return -1;
	 }
	 while (!infile.eof()) {
		  infile.read(ch, FLUSH_NUM);
		  outfile.write(ch, infile.gcount());//写入读入的成功个数
	 }
	 delete[]ch;//记得释放
	 infile.close();//记得关闭
	 outfile.close();//记得关闭
	 return 0;
} 

3. 与系统命令交互

  可以使用 system、_popen 函数等与系统命令交互。使用系统的xcopy等命令,可以实现非常高效的文件复制。这里不再具体展开。

最后

  C++中的流对象普通格式化输入/输出方式,如 >> 和 << 等方式会进行严格的类型检查,虽然安全性提高,但是会损失效率。因此涉及到大内存的读写,应该使用read/write的二进制操作方式。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值