0

I am trying to understand the code behind the copy command which copies a file from one place to other.I studied c++ file system basics and have written the following code for my task.

#include<iostream>
#include<fstream>

using namespace std;

main()
{
    cout<<"Copy file\n";
    string from,to;
    cout<<"Enter file address: ";
    cin>>from;
    ifstream in(from,ios::in | ios::binary);
    if(!in)
    {
        cout<<"could not find file "<<from<<endl;
        return 1;
    }
    cout<<"Enter file destination: ";
    cin>>to;
    ofstream out(to,ios::out | ios::binary);
    char ch;
    while(in.get(ch))
    {
        out.put(ch);
    }
    cout<<"file has been copied\n";
    in.close();
    out.close();
}

Though this code works but is much slower than the copy command of my OS which is windows.I want to know how I can make my program faster to reduce the difference between my program's time and the my OS's copy command time.

Reshad
  • 220
  • 5
  • 19

3 Answers3

1

Reading one byte at time is going to waste a lot of time in function calls... use a bigger buffer:

char ch[4096];
while(in) {
    in.read(ch, sizeof(ch));
    out.write(ch, in.gcount());
}

(you may want to add some more error handling, e.g. out may go in a bad state and the like)

(the most C++-ish way is reported here, but takes advantage of streambuf functionalities that typically a beginner rarely has reason to know, and to me is also way less instructive)

Community
  • 1
  • 1
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
0

You have correctly opened the file for binary read and binary write. However instead of reading characters(which is not meaningful in binary format), use istream::read and ostream::write.

Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
0

Like other answers say, use bigger buffers. I'd go for 1MB. But there's a lot more to it.

Also, avoid stream lib and FILE stuff. They buffer the data so you get 2 memcpy calls instead of 1. Disabling buffering on the streams can achieve a similar result, but I think you're better of using the system calls directly.

And one last thing, on the "do it yourself" front. You must check the return values from read and write calls. They may read/write less bytes than you ask them to.

If you can manage a circular buffer, you should switch read/wrote whenever the function returns short... disk may be more ready for reading or for writing so no point in wasting time waiting instead of switching to the other thing you have to do.

And now the very last thing you might want to explore- look into the sendfile system call. It was built to speed up web servers by doing all the copy in the kernel and avoiding context switches and memcpys, but may serve here if it works with two disk file descriptors.

BitWhistler
  • 1,439
  • 8
  • 12