views:

92

answers:

2

this is a code snippet taken from https://forums.embarcadero.com/message.jspa?messageID=219481

if FileExists(dstFile) then
begin
  Fs := TFileStream.Create(dstFile, fmOpenReadWrite);
  try
    Fs.Seek(Max(0, Fs.Size-1024), soFromBeginning);
    // alternatively:
    // Fs.Seek(-1024, soFromEnd);
    Http.Request.Range := IntToStr(Fs.Position) + '-';
    Http.Get(Url, Fs);
  finally
    Fs.Free;
  end;
end;

i do not understand what exactly is off-set and why Max(0,Fs.Size-1024) in its placeholder and if you go below(in code)

// alternatively:
    // Fs.Seek(-1024, soFromEnd);

what exactly is '-1024'...why do the always use 1024/-1024?? and would fs.size alone in the offset paceholder work( i am tring to make a download manage with pause resume support) and would replacing tfilestream with tmemmorystream in code above have any effect on program?

if it matters :i use d2007 and d2010

+5  A: 

Looks like you're seeking to 1024 from the end of the file (or 0, if the file isn't yet that big). It's all got to do with resuming a transmission. you figure that the end of your file is corrupt. Trim off the crap (or start over from 0) so you aren't adding good data after bad.

Analogy: you're building an ice castle. It gets dark and you get freezing rain overnight. The next day, you get your chainsaw and saw off an inch of crud, exposing the good clean ice. Now you start building from there.

Chris Thornton
+1 for the analogy :D
MarkRobinson
thanks 4 the answer +1 for anology from me too :)
Omair Iqbal
+3  A: 

Since this is trying to create a download manager that can stop and resume downloads, the idea here is that when you resume, it wants to step back a little bit and re-request some of the data that was previously sent just in case the disconnect was caused by an error that caused the data received to be corrupted. Most download managers that I've seen will step back by at least 4 KB; looks like this one is only doing 1 KB.

If you put fs.Size alone in the placeholder then it wouldn't step back at all, which could leave you open to the possibility of corrupt data.

And replacing TFileStream with TMemoryStream would mean that you're downloading to RAM instead of to disc, and if the computer crashes or loses power or your app crashes somehow, all the progress is lost. So that's not a good idea. Also, downloading to RAM limits the size of your download to the available size of your address space, which would make downloading large files (ISOs of DVDs, for example) either impossible or at least much more difficult than it needs to be.

Mason Wheeler
thanks mason, +1 for a good and detailed answer. i want to use memmory stream because it has savetofile method and tfilestream doesnt
Omair Iqbal
@omair: TFileStream doesn't need it because it's already associated with a file. You're basically cutting out the middleman by using TFileStream instead.
Mason Wheeler
@ mason where does tfilestream save our data on hard disk i mean at which location?
Omair Iqbal
@omair: In the code example you gave above, it saves it to `dstfile`, gradually writing each data packet to it as the data arrives.
Mason Wheeler
@ mason which is better in terms of performance ,using tfilestream or declaring a file variable and then using BlockWrite(),thanks again for your help and patience :)
Omair Iqbal
@Omair: You want to use the filestream. When you're streaming directly to the hard drive, data's coming in over the network a lot more slowly than your CPU and hard drive can handle it, so it gets saved immediately and performance isn't really an issue. What's really important here is correctness: Making sure that the data gets saved immediately so as to minimize the possibility of losing anything if the program or the system crashes. And TFileStream make that task a lot easier.
Mason Wheeler