I want to download a file from a HTTP server via a file stream and only read (and save to a file) the first few lines, say 100. After reading the first 100 lines the file stream must end: so I do NOT want to download or read the entire file.
Below you can find what I have so far. The website is just an example. Can someone guide me in the right direction?
const
myURL = https://graphical.weather.gov/xml/DWMLgen/schema/latest_DWML.txt
var
fs: TMemoryStream;
http: TIdHTTP;
begin
fs := TMemoryStream.Create;
http := TIdHTTP.Create(nil);
try
fs.Position := 0;
http.Get(myURL, fs);
fs.SaveToFile('test.xml');
finally
fs.Free;
http.free
end;
end;
If the HTTP server supports byte ranges for the desired URL (via the
Range
request header), you can request just the specific bytes you want, and that is all the server will send. You can use theTIdHTTP.Request.Range
property for that when callingTIdHTTP.Get()
. To discover if the server supports byte ranges, useTIdHTTP.Head()
first to get the URL's headers, and then check if there is anAccept-Ranges: bytes
header present (see theTIdHTTP.Response.AcceptRanges
property).If the server does not support byte ranges, you will have to continue using the code you currently have, just make some changes to it:
Instead of calling
fs.SaveToFile()
, create a separateTFileStream
object and pass theTMemoryStream
to itsCopyFrom()
method, that way you can specify exactly how many bytes to save.Use the
TIdHTTP.OnWork
event, or use aTIdEventStream
, or derive a customTStream
that overridesWrite()
, in order to keep track of how many bytes are being downloaded, so you can abort the download (by raising an exception, likeEAbort
viaSysUtils.Abort()
) once the desired number of bytes have been received.Of course, either approach is byte oriented not line oriented. If you need to be line-oriented, and particularly if the lines are variable length, then you will have to use the second approach above, using
TIdEventStream
or a customTStream
, so you can implement line parsing logic and save only complete lines to your file, and then abort once you have received the desired number of lines.