I want to copy all the files from one directory to another using the fread() and fwrite()-statements.
Some of these files are rather large in size, and that's why I want to calculate who long the transfer will take.
(Later I will use this information to show a progress bar containing remaining transfer time, percent data transferred so far and (possibly) the actual transfer speed).
The problem is:
When I try to do a full transfer of the biggest file in the list (the one with index 0 in the fdata-struct) I find that the transfer time is much higher than the calculated time. I think this is strange since I'm using the filecopy routine in both cases..*
<Background information>:
First I obtain a filelist from the source directory (srcdir) using opendir() and readdir(). The information is put in the struct finfo named "fcont".
struct finfo {
string filename;
unsigned long fsize;
float ttime;
bool operator() (finfo i, finfo j)
{
if(i.fsize == j.fsize)
return i.filename < j.filename;
return (i.fsize > j.fsize);}
} fstruct;
vector<finfo> fdata;
// ==================
// == Main program ==
// ==================
const string INFO1 = "Error using opendir(). Terminating..";
FILE *iFile, *oFile;
DIR *pdir;
string srcdir;
finfo fcont;
srcdir = argv[1];
pdir = opendir(srcdir.c_str());
if (!pdir)
{
cout << INFO1 << endl;
exit(1);
}
while ((pent=readdir(pdir)))
{
if (pent->d_name[0] != '.')
{
fcont.filename = pent->d_name;
iFile = openfile(srcdir + "/" + pent->d_name,"read");
fcont.fsize = filesize(iFile,"TRUE");
fdata.push_back(fcont);
}
}
cout << endl;
closedir(pdir);
Then the struct fdata is sorted by file size and by file name if the file size is equal.
sort(fdata.begin(),fdata.end(),fstruct);
The next step is to calculate the total number of buffers to be transferred for to copy the entire file.
// ======================================================
// == Calculating number of buffers to be transferred. ==
// ======================================================
AntBuff = fdata[0].fsize / BUFSIZE;
In this case I'm using:
DELTA = 4
DELTABUFF = 10000
BUFSIZE = 8192
To calculate the average transfer time in seconds I do DELTA iterations each containing reading and writing
DELTABUFF number of buffers with BUFSIZE while I measure the elapsed time for these read and write operations.
For each iteration I close both the source and destination file and deletes the destination file.
The average transfer time is the sum of transfer times divided with DELTA.
At last I calculate the transfer time for each file in the fdata struct by calculating ((fsize/BUFSIZE)/SnittBuff).
// ========================================================
// == Calculating average time for transferring buffers ==
// ========================================================
for (i=1; i <= DELTA; i++)
{
iFile = openfile(srcfile,"read");
oFile = openfile(dstfile,"write");
// == Start time ==
gettimeofday(&tim,NULL);
t1 = tim.tv_sec + (tim.tv_usec/1000000.0);
// == Reading source file and writing to destination file DELTABUFF number of buffers with size BUFSIZE ==
for (iSpeed = 1;iSpeed <= DELTABUFF;iSpeed++)
{
retval = filecopy(iFile,oFile);
}
// == End time ==
gettimeofday(&tim,NULL);
t2 = tim.tv_sec + (tim.tv_usec/1000000.0);
// == Calculating number of buffers transferred pr.second ==
CalcAntBuff = DELTABUFF/(t2-t1);
// == Closing source- and destination file ==
fclose(iFile);
fclose(oFile);
// == Deleting destination file ==
if( remove(dstfile.c_str()) != 0 ) {
string str = "Error deleting file " + dstfile;
perror( str.c_str());
}
// == Total sum of number of buffers transferred pr. second
SumBuff = SumBuff + CalcAntBuff;
}
// == Average number of buffers transferred pr. second.
SnittBuff = SumBuff / DELTA;
// ==========================================
// == Calculating transfer time in seconds ==
// ==========================================
for (count=0;count<=fdata.size()-1;count++) {
if (fdata[count].fsize == 0) {
fdata[count].ttime = 0;
}
else
{
AntBuff = fdata[count].fsize / BUFSIZE;
fdata[count].ttime = AntBuff / SnittBuff;
}
}
But the problem is:
When I try to do a full transfer of the biggest file in the list (the one with index 0 in the fdata-struct) I find that the transfer time is much higher than the calculated time. I think this is strange since I'm using the filecopy routine in both cases..
To transfer (copy) the complete file I use the following code:
iFile = openfile(srcfile,"read");
oFile = openfile(dstfile,"write");
gettimeofday(&tim,NULL);
t1 = tim.tv_sec + (tim.tv_usec/1000000.0);
while (size !=0) {
retval = filecopy(iFile,oFile);
}
gettimeofday(&tim,NULL);
t2 = tim.tv_sec + (tim.tv_usec/1000000.0);
fclose(oFile);
fclose(iFile);
The openfile, filesize and filecopy routines:
FILE * openfile(string filename,string access){
FILE *hFile;
if (access == "read")
{
hFile = fopen(filename.c_str(),"rb");
}
else if (access == "write")
{
hFile = fopen(filename.c_str(),"wb");
}
if (errno == 0) {
return hFile;
}
else
exit(0);
}
long filesize(FILE *iFile, bool closefile) {
struct stat buffer;
long fssize;
int fs;
fs = fileno(iFile);
fstat(fs,&buffer);
fssize = buffer.st_size;
if (closefile) {
fclose(iFile);
}
return fssize;
}
int filecopy(FILE *iFile, FILE *oFile){
size = fread(buf,1,BUFSIZE,iFile);
fwrite(buf,1,size,oFile);
return (0);
}