File Size

Hey ppl,

In the below given code, I have already opened a file with pFile, then i open a second file with CFile local
and keep reading from the pFile object and writing the same data to CFile local. Basically i'm copying one file to another.

In the While loop used in the below code i want to compare the Total File size of pFile with the total data written to CFile local,and exit the loop as soon as both the values are equal i.e. when data has been completely copied from file1 to file2. But the while loop is not functioning as it should be, it comes to a premateur end.

I know i can use While(nRead>0) instead of what i have used, But i want to exit the loop by comparing the two values. But i can't figure out why it isn't working.

Any suggestions ?




///////// Code Begins ///////////


DWORD fsize;
DWORD total_written=0;
fsize=pFile->GetLength();

     CFile local(test_file_name,CFile::modeCreate|CFile::modeNoTruncate   |CFile::modeWrite |CFile::typeBinary );  
          local.SeekToEnd();

UINT nRead = pFile->Read(szBuff, 100);            
local.Write(&szBuff,nRead);
total_written=nRead;

while(total_written!=fsize)
{
nRead = pFile->Read(szBuff, 100);            
local.Write(&szBuff,nRead);
total_written+=nRead;
}          


/////////////////////////////////////////////


nitshvAsked:
Who is Participating?
 
DanRollinsCommented:
hi nitshv,
Do you have any additional questions?  Do any comments need clarification?

-- Dan
0
 
AxterCommented:
How is it not working?
How much is written?
How premature is it?

Please give exact results
0
 
AxterCommented:
Please show all the relevent code.
You code does not show how pFile gets open, and what happens after it's open.
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

 
AxterCommented:
You're using an & in the Write function.
I don't think that belongs there, and that could be thrown your code off.
It should be the following:
local.Write(szBuff,nRead);

And NOT local.Write(&szBuff,nRead);

You have this twice in your code.
0
 
GlennDeanCommented:
Try the minor modification to see if this works:

UINT nRead = pFile->Read(szBuff, 100);            
local.Write(szBuff,nRead);  //Note not using &szBuff
total_written=nRead;

while(total_written < fsize)
{
  nRead = pFile->Read(szBuff, 100);            
  local.Write(szBuff,nRead);
  total_written+=nRead;
}          


0
 
GlennDeanCommented:
It's unclear why it end prematurely, but one thing it could be is you're using test_file_name both as the file to transfer from and to.  I made test_file_name as "MyFile.exe" and then wrote the following code and it worked great.

DWORD fsize;
char szBuff[256];
DWORD total_written=0;
DWORD dwLocalSize = 0;
fsize=pFile->GetLength();

CFile local("temp.txt",CFile::modeCreate | CFile::modeWrite |CFile::typeBinary );  
local.SeekToEnd();

UINT nRead = pFile->Read(szBuff, 100);            
local.Write(szBuff,nRead);
total_written=nRead;

dwLocalSize = local.GetLength();
while(total_written!=fsize)
{
  nRead = pFile->Read(szBuff, 100);            
         
  local.Write(szBuff,nRead);
  total_written+=nRead;
  TRACE("\nnRead=%ld,total_written=%ld",nRead,total_written);
  ::Sleep(1);
}  
     
DWORD dwLocal = local.GetLength();
if (dwLocal!=fsize)
{
  local.Close();
  local.Open("temp.txt",CFile::modeNoTruncate |   CFile::modeWrite |CFile::typeBinary );  
  dwLocal = local.GetLength();
  ASSERT(dwLocal==fsize);  
}

  Give the above a shot,

      Glenn          



0
 
SrinivasaRaoCommented:
Hai,
  As axert pointed it out, its not necessary to send address of a pointer to the CFile::Write() function. And second point i am suggesting is, You are opening file as given below :
CFile local(test_file_name, CFile::modeCreate | CFile::modeNoTruncate|CFile::modeWrite |CFile::typeBinary
);

Please remove CFile::modeNoTruncate from the mode of opening. Because you keep this as an option, if the file "test_file_name" already exists your data will be appended. So both lengths can be get equalled at any moment. However, if file is not there your code should work properly by modifying
 local.Write(&sizeBuf, nRead) ;
to
 local.Write(sizeBuf, nRead) ;

Respond with result.
BSR
0
 
DanRollinsCommented:
Simpler than getting the source file length... just read the source file and when the return value is 0, you are finished:

CFile fSrc, fDst;

fSrc.Open( "MySource.txt", CFile::modeRead |CFile::shareDenyNone );

fDst.Open( "MyDest.txt", CFile::modeCreate |CFile::shareExclusive );

char szBuf[1024];
int nTotal= 0;
do {  
   int nActual= fSrc.Read( szBuf, sizeof(szBuf) );
   fDst.Write( szBuf, nActual );
   nTotal += nActual;
   TRACE("\nRead=%d,SoFar=%d",nRead,nTotal);
} while nActual != 0;

fSrc.Close();
fDst.Close();

Simpler is better
-- Dan
0
 
nitshvAuthor Commented:

Here is the complete code, what i'm basically doing is reading a CHttpFile from a server and copying it as a file on local machine.

Dan, the reason why i'm not using while(nActual!=0) is because i want to read the file in segments so that i can resume the file copying if connection to the server is lost, so in order to achieve that i need to know when my local file size reaches total file size so that i can stop the download process.


In the below given code, it works absolutely fine as long as the file size is less than 1MB but for file larger than 1 MB it produces errors during execution.


/////////////////////////////////////////////////////////

DWORD total_written=0;
DWORD fsize=1;

void CResumeDlg::OnCancel()
{
     
     CInternetSession session("My Session");
     CHttpConnection* pServer = NULL;
     CHttpFile* pFile = NULL;
     DWORD dwRet;


     try
     {
         
          CString strServerName;
     


          pServer = session.GetHttpConnection("localhost");

         
          CString test_file_name="test.exe";
         
     
          pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET, test_file_name);          
          pFile->SendRequest();
          if(pFile->QueryInfoStatusCode(dwRet)==0)
               AfxMessageBox("Fail");            
     
               
         
          if (dwRet == HTTP_STATUS_OK)
          {

               char szBuff[1024*20];
               fsize=pFile->GetLength();

               
               
               if(fsize==total_written)
               {

                    AfxMessageBox("done");
                    return;

               }    

               
             CFile local(test_file_name,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite |CFile::typeBinary );  
             
             
             pFile->Seek((long)total_written,CFile::begin);                
     
             UINT nRead = pFile->Read(szBuff, 1024*20);            

             local.SeekToEnd();
            local.Write(szBuff,nRead);    
             total_written+=nRead;

             local.Close();              
           
               
          }
         
       
          delete pFile;
          delete pServer;

         
     }


     catch (CInternetException* pEx)
     {
               
     }

     session.Close();
     
     OnCancel();
     

}



///////////////////////////////////////////////


0
 
DanRollinsCommented:
>>but for file larger than 1 MB it produces errors during execution.

It would help to know what errors it produces.

As always, I suggest removing the try...catch handling so that you can see the actual errors.  Nobody ever does this though I can't imagine why...

I'd also use:

  LONG nNewPos= pFile->Seek((long) total_written,CFile::begin);                

and then I'd examine nNewPos to see if all is well.

>>the reason why i'm not using while(nActual!=0) is because i want to read the file in segments so that i can resume the file copying...

Think about it... you can still use while(nActual!=0) in any case.  When the return is 0, you have reached the end of the source file.

There are several other oddities in this last post:
1) Why are you doing this in an OnCb\ncel() handler?

2) Why is there no loop that will keep reading until the end of the file?  Your code just attempts to read 20K for the file, then ends.

3) Why are you opening with the with CFile::modeCreate when you know that the file already exists?

4) Why do you not check the return values of calls such as local.SeekToEnd() even though you know that errors are happening?

-- Dan
0
 
nitshvAuthor Commented:
Ok I have solved the problem, the error was coming due to stack overflow so i removed the recursion.

But now there's another problem that has come up. I'm unable to get the correct file size of the remote file.

I use the following code to get the file size and it gives me incorrect file size.



////////////////////////////////////


     CInternetSession session("My Session");
     CHttpConnection* pServer = NULL;
     CHttpFile* pFile = NULL;
     DWORD dwRet;


          CString strServerName;

          pServer = session.GetHttpConnection("localhost");

         
          CString test_file_name="/test.zip";
         
     
          pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET, test_file_name);          
          pFile->SendRequest();
          if(pFile->QueryInfoStatusCode(dwRet)==0)
               AfxMessageBox("Fail");            
     
     
               fsize=pFile->GetLength();
                 
               char buff[5];
                    sprintf(buff,"%d",fsize);
                    AfxMessageBox(buff);


///////////////////////////////////////////////////////////
0
 
DanRollinsCommented:
Web servers are not required to provide the length of a file.  That is why, when browsing, the IE progress guage is sometimes shown as empty.

You can eyeball the server response headers by using
  CString sRespHeadersRcvd;
  pFile->QueryInfo( HTTP_QUERY_RAW_HEADERS_CRLF, sRespHeadersRcvd );

and you might consider checking the return from QueryInfoStatusCode to see if the file was found.  You could also override the StatusCallback to learn the progress of the request.
=-=-=-=-=-=-=-=-=-=-=-=-
Call it beating a dead horse... but I have already stated that you don't need to know the length of the file in order to read all of it.

-- Dan
0
 
nitshvAuthor Commented:
Alrite Dan thanks for your help....i think i will stick to your method instead of getting the file size.

But Now, whom do i give points to ?

0
 
DanRollinsCommented:
-- Dan
0
 
MoondancerCommented:
Force accepted by moderator.  In the event Asker returns with additional needs related to this question, please respond and continue the collaboration process.
Thank you,
Moondancer
Community Support Moderator @ Experts Exchange
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.