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

Firemonkey Android读取大于1MB的InputStream返回0问题求助

问题原因
  • 第三方文件管理应用提供的FileProvider返回的InputStream存在兼容缺陷,调用available()获取大文件长度时会触发缓冲区预读,指针未正确复位,导致后续读取内容前出现多段0值。
  • 代码直接用Delphi默认的2字节Char接收Java InputStream返回的单字节值,虽然小文件场景下显示正常,但存在高位补0的隐藏问题,容易和实际读取到的0值混淆。
  • Firemonkey 10.4.1版本对Android原生InputStream的直接调用存在已知的小概率读取偏移bug,单字节读取模式在大文件场景下兼容性更差。
解决方案

按照以下规则修改代码即可解决问题:

  1. 调整读取顺序,优先读取文件内容,后获取文件长度,避免available()调用对读取指针的影响
  2. 用Byte类型接收单字节读取结果,避免宽字符类型干扰
  3. 使用Firemonkey提供的TJavaInputStream包装原生JInputStream,转换成Delphi标准流操作,兼容性更高

修改后的可运行参考代码:

uses
  Androidapi.Helpers, Androidapi.JNI.JavaTypes, Androidapi.JNI.Net,
  System.Classes, Androidapi.JNI.GraphicsContentViewText;

function StartupFileGet : string;
var
  intent: JIntent;
  uri: Jnet_Uri;
  uriStr: String;
  InStrm: JInputStream;
  delphiStream: TStream;
  buf: array[0..1] of Byte;
  readCount: Integer;
  total: integer;
begin
  Result := '';
  intent := TAndroidHelper.Activity.getIntent;
  if intent = nil then Exit;

  if TJIntent.JavaClass.ACTION_VIEW.equals(intent.getAction) then
  begin
    uri := intent.getData;
    uriStr := JStringToString(uri.toString);
    Result := uriStr + '=';

    InStrm := TAndroidHelper.Activity.getContentResolver.openInputStream(uri);
    if InStrm = nil then Exit;

    try
      delphiStream := TJavaInputStream.Create(InStrm);
      try
        // 先读取前2字节,不提前调用长度获取接口
        readCount := delphiStream.Read(buf, 2);
        if readCount = 2 then
        begin
          Result := Result + Chr(buf[0]) + Chr(buf[1]);
        end;
        // 最后获取总长度
        total := delphiStream.Size;
        Result := Result + ', ' + IntToStr(total);
      finally
        delphiStream.Free;
      end;
    except
      Result := Result + ', exception';
    end;
    InStrm.close;
  end;
end;

修改后测试大文件即可正常读取到PK的zip头标识,不会出现前导0的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 11:39:03