🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.internet.web
10 messages
10 total messages Started by CJ Thu, 01 Nov 2007 17:00
Doing an internet resuming on a file
#181
Author: CJ
Date: Thu, 01 Nov 2007 17:00
19 lines
1640 bytes
Can someone explain the following to me please.

I am working with some code that will download a file from the internet.
But there are a few things that I am very unsure of while downloading the 
file.

1. What function do you use when you are trying to resume the file without
using the Wininet cache?

Lets say you download half of a file, what can I store maybe in an .ini file
that will show me where I stopped, this way I can resume the file again.
I don't want to use the Wininet cache system for the files, I would like to
do it all by setting the pointer somewhere myself.

This is all new to me so please be simple.

Thanks

CJ
Re: Doing an internet resuming on a file
#182
Author: Remy Lebeau (TeamB)
Date: Thu, 01 Nov 2007 18:15
18 lines
1637 bytes
"CJ" <cluis@yahoo.com> wrote in message 
news:472a0628@newsgroups.borland.com...

> Lets say you download half of a file, what can I store maybe
> in an .ini file that will show me where I stopped, this way I
> can resume the file again.  I don't want to use the Wininet
> cache system for the files, I would like to do it all by setting
> the pointer somewhere myself.

To do what you are asking, you will have to use your own file handle.  That 
means using InternetReadFile() and WriteFile() to download the data yourself 
manually insted of letting WinInet do it for you.  Since you would be using 
your own file handle, then you can store the file whereever you want and use 
whatever filenme you want.


Gambit 
Re: Doing an internet resuming on a file
#183
Author: CJ
Date: Thu, 01 Nov 2007 18:48
18 lines
1488 bytes
Am I still going to use the following function in this order?

InternetOpen()
InternetConnect()
HttpOpenRequest()
HttpSendRequest()
InternetReadFile()
FileStream->Write()

Thanks




> To do what you are asking, you will have to use your own file handle. 
> That means using InternetReadFile() and WriteFile() to download the data 
> yourself manually insted of letting WinInet do it for you.  Since you 
> would be using
Re: Doing an internet resuming on a file
#184
Author: CJ
Date: Thu, 01 Nov 2007 20:15
114 lines
3795 bytes
Forget about this code, I saw an example of something you did online
before.  There is one part in the code that it's cashing in, I am not sure
what kind of value is supposed to be in there.  Question, isn't new 
FileStream
supposed to be called before you check the FileStream->Size  ?????

TFileStream* FileStream;

1.  if(FileName != "")
2. {
3.   if(FileExists(FileName))
4.   {
5.    if(AcceptRanges.Pos("bytes") != 0)
6.    {
7.     AnsiString Range = ("Range: bytes=" + AnsiString(FileStream->Size) + 
"-\r\n");
8.     if(!HttpAddRequestHeaders(hFile, Range.c_str(), -1, 
HTTP_ADDREQ_FLAG_ADD))
9.     {
      throw Exception("unable to add range header to file request");
     }
     bIsResuming = true;
    }

------------  The full part of the code that --------------
  SaveDialog = new TSaveDialog(NULL);
  try
  {
   if(SaveDialog->Execute())
    FileName = SaveDialog->FileName;
  }
  __finally
  {
   delete SaveDialog;
  }

  if(FileName != "")
  {
   if(FileExists(FileName))
   {
    if(AcceptRanges.Pos("bytes") != 0)
    {
     AnsiString Range = ("Range: bytes=" + AnsiString(FileStream->Size) + 
"-\r\n");
     if(!HttpAddRequestHeaders(hFile, Range.c_str(), -1, 
HTTP_ADDREQ_FLAG_ADD))
     {
      throw Exception("unable to add range header to file request");
     }
     bIsResuming = true;
    }
   }

   if(!HttpSendRequest(hFile, NULL, 0, NULL, 0))
   {
    throw Exception("unable to send file request to the server");
   }
   if(bIsResuming)
    FileStream = new TFileStream(FileName, fmOpenReadWrite | 
fmShareDenyWrite);
   else
    FileStream = new TFileStream(FileName, fmCreate);

   try
   {
    if(bIsResuming)
    {
     FileStream->Seek(0, soFromEnd);
     dwBytesRead = FileStream->Position;
    }
    else
     dwBytesRead;

    ProgressBar->Position = (dwBytesRead * 100 / dwBufLen);
    ProgressBar->Max = dwContentLen;

    while(InternetReadFile(hFile, Data, 1024, &dwBytesRead))
    {
     if(dwBytesRead == 0)
      break;

     iWritten = 0;
     DataPtr = Data;

     do
     {
      iWritten = FileStream->Write(DataPtr, dwBytesRead);
      if(iWritten < 1)
       throw Exception("unable to write to local file");

      DataPtr += iWritten;
      dwBytesRead -= iWritten;

      ProgressBar->StepBy(iWritten);
      Application->ProcessMessages();
     }
     while(dwBytesRead != 0);
    }

    if(FileStream->Size != dwContentLen)
     throw Exception("File saved is incomplete");
   }
   __finally
   {
    delete FileStream;
   }
  }
 }
 __finally
 {
  if(hFile) InternetCloseHandle(hFile);
  if(hConnect) InternetCloseHandle(hConnect);
  if(hSession) InternetCloseHandle(hSession);
 }
Re: Doing an internet resuming on a file
#185
Author: Remy Lebeau (TeamB)
Date: Thu, 01 Nov 2007 22:08
97 lines
3852 bytes
"CJ" <cluis@yahoo.com> wrote in message 
news:472a33c4$1@newsgroups.borland.com...

> There is one part in the code that it's cashing in, I am not
> sure what kind of value is supposed to be in there.

The size of the file that was previously downloaded.

> isn't new FileStream supposed to be called before you
> check the FileStream->Size  ?????

Yes.  Here is an updated example:

    SaveDialog = new TSaveDialog(NULL);
    try
    {
        if( SaveDialog->Execute() )
            FileName = SaveDialog->FileName;
    }
    __finally
    {
        delete SaveDialog;
    }

    if( FileName != "" )
    {
        TSearchRec sr;
        if( FindFirstFile(FileName, faAnyFile, sr) )
        {
            FindClose(sr);

            if( (AcceptRanges.Pos("bytes") != 0) && (sr.Size > 0) )
            {
                AnsiString Range = ("Range: bytes=" + AnsiString(sr.Size) + 
"-\r\n");
                if( !HttpAddRequestHeaders(hFile, Range.c_str(), -1, 
HTTP_ADDREQ_FLAG_ADD) )
                    throw Exception("unable to add range header to file 
request");
                bIsResuming = true;
            }
        }

        if( !HttpSendRequest(hFile, NULL, 0, NULL, 0) )
            throw Exception("unable to send file request to the server");

        if( bIsResuming )
            FileStream = new TFileStream(FileName, fmOpenReadWrite | 
fmShareDenyWrite);
        else
            FileStream = new TFileStream(FileName, fmCreate);

        try
        {
            if( bIsResuming )
                FileStream->Position = sr.Size;

            dwBytesRead = FileStream->Position;

            ProgressBar->Position = (dwBytesRead * 100 / dwBufLen);
            ProgressBar->Max = dwContentLen;

            while( InternetReadFile(hFile, Data, 1024, &dwBytesRead) )
            {
                if( dwBytesRead == 0 )
                    break;

                iWritten = 0;
                DataPtr = Data;

                do
                {
                    iWritten = FileStream->Write(DataPtr, dwBytesRead);
                    if( iWritten < 1 )
                        throw Exception("unable to write to local file");

                    DataPtr += iWritten;
                    dwBytesRead -= iWritten;

                    ProgressBar->StepBy(iWritten);
                    Application->ProcessMessages();
                }
                while( dwBytesRead != 0 );
            }

            if( FileStream->Size != dwContentLen )
                throw Exception("File saved is incomplete");
        }
        __finally
        {
            delete FileStream;
        }
    }


Gambit 
Re: Doing an internet resuming on a file
#186
Author: CJ
Date: Fri, 02 Nov 2007 01:17
16 lines
1683 bytes
I really do appreciate your help, this works great.

I have another question if you don't mind.

How do you download the file using two threads?  Lets
say I want to download a 9MB file without taking too
long.  I want to download I guess half of the file using
the first thread, then the next half using the second thread.

Where do I start?  I know absolutely nothing about threads.
All I have ever read about it is you better be careful or the
program will crash.  So I never messed with it at all.


Thanks again.
CJ
Re: Doing an internet resuming on a file
#187
Author: Remy Lebeau (TeamB)
Date: Fri, 02 Nov 2007 16:47
19 lines
1858 bytes
"CJ" <cluis@yahoo.com> wrote in message 
news:472a7a8a$1@newsgroups.borland.com...

> How do you download the file using two threads?

If the server supports the "Range" request header, then you can have one 
thread send a request for one range of bytes, and the other thread can 
request a different range of bytes.  Then simply have them download to 
different areas of the same file, or download to separate files that you can 
concatenate together later on.

> Where do I start?  I know absolutely nothing about threads.

I suggest you look at the VCL's TThread class, and look at 
Borland/CodeGear's examples that ship with the IDE.


Gambit 
Re: Doing an internet resuming on a file
#188
Author: CJ
Date: Fri, 02 Nov 2007 18:39
16 lines
1902 bytes
> If the server supports the "Range" request header, then you can have one 
> thread send a request for one range of bytes, and the other thread can 
> request a different range of bytes.  Then simply have them download to

I have seen program do this before when copying files from one location
to another.  I don't remember the name of the program, but I have seen it
use up to four threads to copy files from one pc to another.

I still can't fathom the idea of two or more threads writing to the same 
file.

Do you know of any code examples out there that does this?  I would like
to look and see if I can understand any of it at all.

Thanks
CJ
Re: Doing an internet resuming on a file
#189
Author: Remy Lebeau (TeamB)
Date: Fri, 02 Nov 2007 19:02
13 lines
1714 bytes
"CJ" <cluis@yahoo.com> wrote in message 
news:472b6ef8@newsgroups.borland.com...

> I still can't fathom the idea of two or more threads writing
> to the same file.

Simply create two separate streams to the same file, position them within 
the file accordingdly, and then make sure each thread does not cross over 
into another thread's area of the file when writing to it.


Gambit 
Re: Doing an internet resuming on a file
#190
Author: CJ
Date: Fri, 02 Nov 2007 20:04
8 lines
1606 bytes
> Simply create two separate streams to the same file, position them within 
> the file accordingdly, and then make sure each thread does not cross over 
> into another thread's area of the file when writing to it.

Thanks, I will have to experiment and try that.  Thanks for all of your
help once again.

CJ
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads