通过IdHTTP读取和保存部分文件流 [英] Read and save part of file stream via IdHTTP

查看:137
本文介绍了通过IdHTTP读取和保存部分文件流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过文件流从HTTP服务器下载文件,并且仅读取(并保存到文件)前几行,例如100。读取前100行后,文件流必须结束:所以我这样做不想下载或读取整个文件。

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;


推荐答案

如果HTTP服务器支持所需URL的字节范围(通过 范围 请求标头),您可以仅请求所需的特定字节,这就是服务器将发送的所有字节。调用 TIdHTTP.Get()时,可以使用 TIdHTTP.Request.Range 属性。若要发现服务器是否支持字节范围,请先使用 TIdHTTP.Head()来获取URL的标头,然后检查是否有 接受范围:字节 标头(请参见 TIdHTTP.Response.AcceptRanges 属性)。

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 the TIdHTTP.Request.Range property for that when calling TIdHTTP.Get(). To discover if the server supports byte ranges, use TIdHTTP.Head() first to get the URL's headers, and then check if there is an Accept-Ranges: bytes header present (see the TIdHTTP.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:


  • 而不是调用 fs.SaveToFile( ),创建一个单独的 TFileStream 对象,然后将 TMemoryStream 传递给其 CopyFrom() 方法,这样您就可以确切指定要保存的字节数。

  • Instead of calling fs.SaveToFile(), create a separate TFileStream object and pass the TMemoryStream to its CopyFrom() method, that way you can specify exactly how many bytes to save.

使用 TIdHTTP.OnWork 事件,或使用 TIdEventStream ,或派生自定义的 TStream 覆盖 Write(),以便跟踪正在下载的字节数,因此您可以中止下载(通过引发异常,例如<$ c收到所需的字节数后,通过 SysUtils.Abort())通过$ c> EAbort 。

Use the TIdHTTP.OnWork event, or use a TIdEventStream, or derive a custom TStream that overrides Write(), in order to keep track of how many bytes are being downloaded, so you can abort the download (by raising an exception, like EAbort via SysUtils.Abort()) once the desired number of bytes have been received.

当然,两种方法都是面向字节而非面向行。如果您需要面向行,特别是如果行的长度可变,则必须使用上述第二种方法,即使用 TIdEventStream 或自定义的 TStream ,因此您可以实现行解析逻辑,仅将完整的行保存到文件中,然后在收到所需的行数后中止操作。

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 custom TStream, 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.

这篇关于通过IdHTTP读取和保存部分文件流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆