我想通过文件流从 HTTP 服务器下载文件,并且只读取(并保存到文件)前几行,例如 100 行。读取前 100 行后,文件流必须结束:所以我不想下载或阅读整个文件。
您可以在下面找到我到目前为止所拥有的内容。该网站只是一个例子。有人可以引导我走向正确的方向吗?
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 的字节范围(通过Range https://www.rfc-editor.org/rfc/rfc2616#section-14.35请求头),您可以只请求您想要的特定字节,这就是服务器将发送的所有字节。您可以使用TIdHTTP.Request.Range
调用时的属性TIdHTTP.Get()
。要发现服务器是否支持字节范围,请使用TIdHTTP.Head()
首先获取URL的头部,然后检查是否有Accept-Ranges: bytes https://www.rfc-editor.org/rfc/rfc2616#section-14.5存在标头(请参阅TIdHTTP.Response.AcceptRanges
财产)。
如果服务器不支持字节范围,您将不得不继续使用当前的代码,只需对其进行一些更改:
-
而不是打电话fs.SaveToFile()
,创建一个单独的TFileStream
对象并传递TMemoryStream
to its CopyFrom() http://docwiki.embarcadero.com/Libraries/en/System.Classes.TStream.CopyFrom方法,这样您就可以准确指定要保存多少字节。
-
Use the TIdHTTP.OnWork
事件,或使用TIdEventStream
,或派生出一个自定义TStream
覆盖Write()
,为了跟踪正在下载的字节数,因此您可以中止下载(通过引发异常,例如EAbort
via SysUtils.Abort()
)一旦收到所需的字节数。
当然,无论哪种方法面向字节 not 面向线。如果您需要面向行,特别是如果行的长度可变,那么您将必须使用上面的第二种方法,使用TIdEventStream
或自定义TStream
,因此您可以实现行解析逻辑并仅将完整行保存到文件中,然后在收到所需行数后中止。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)