You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Indy TIdHTTP正确读取网络电台的无限流?

问题根源

网络电台的流是无限持续的,TIdHTTP.Get()会一直读取直到服务器主动关闭连接,所以你的程序会卡在Get()调用上,永远不会执行后续代码。

解决方案:分段读取并检测XML

你需要手动控制读取过程,每次读取一小段数据,同时检查是否出现XML的特征(比如<开头的标记),一旦检测到目标XML或者读取到足够数据,就停止读取。

修改后的代码示例:

procedure TformMain.GetUrlStream(url: string; var m: TMemoryStream);
var
  IdHTTP1: TIdHTTP;
  IO: TIdSSLIOHandlerSocketOpenSSL;
  Buffer: array[0..4095] of Byte;
  BytesRead: Integer;
  TempStr: string;
  FoundXML: Boolean;
begin
  IdHTTP1 := TIdHTTP.Create(nil);
  try
    IO := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP1);
    IO.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
    IdHttp1.IOHandler := IO;
    IdHttp1.ConnectTimeout := 5000;
    IdHttp1.ReadTimeout := 10000; // 设置读取超时,防止无数据时卡住
    IdHttp1.Request.UserAgent := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36';
    IdHttp1.Request.Connection := 'keep-alive'; // 无限流不需要close,保持连接

    // 手动发送GET请求,避免自动读取全部流
    IdHTTP1.Request.Method := 'GET';
    IdHTTP1.Connect(url, IdHTTP1.DefaultPort);
    IdHTTP1.SendRequest(IdHTTP1.Request.Method, url);
    IdHTTP1.ReadResponseHeaders;

    FoundXML := False;
    m.Clear;
    while not FoundXML do
    begin
      // 每次读取4KB数据块
      BytesRead := IdHTTP1.IOHandler.Read(Buffer, SizeOf(Buffer));
      if BytesRead <= 0 then Break;

      // 将读取到的数据写入内存流
      m.WriteBuffer(Buffer, BytesRead);

      // 检测XML特征(可根据实际元数据格式调整,比如找特定根节点)
      SetString(TempStr, PChar(@Buffer[0]), BytesRead);
      if (Pos('<', TempStr) > 0) and (Pos('>', TempStr) > 0) then
      begin
        FoundXML := True;
        // 可选:多读一次确保XML片段完整
        BytesRead := IdHTTP1.IOHandler.Read(Buffer, SizeOf(Buffer));
        if BytesRead > 0 then
          m.WriteBuffer(Buffer, BytesRead);
      end;
    end;
  finally
    IdHTTP1.Disconnect;
    IdHTTP1.Free;
  end;
end;
关键说明
  • 放弃Get()的自动读取逻辑,改用手动连接、发送请求、读取响应头的方式,完全控制读取过程。
  • 设置ReadTimeout,如果超过指定时间未读取到数据,会抛出异常,可捕获后终止读取。
  • 分段读取数据并实时检测XML特征,找到目标后立即停止,避免无限等待。
  • 你需要根据实际的元数据格式调整检测逻辑,比如已知元数据根节点是<metadata>,可以直接检测该字符串提高准确性。

内容的提问来源于stack exchange,提问作者ratmalwer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 13:17:26