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

Android端DataSnap发送PNG图片遇类型转换及内存溢出问题求助

问题解决:DataSnap传输图片流的类型转换与内存不足问题

问题1:Invalid Typecast(类型转换无效)

初始代码中服务端直接将参数声明为TMemoryStream,但DataSnap在传输流时,实际传递的是TDBXStream(DataSnap封装的流类型),而非原生的TMemoryStream,直接强制转换就会触发类型转换错误。

问题2:大文件传输内存不足

改为TStream后,若仍使用TMemoryStream加载整个文件到内存,在Android设备(内存资源有限)或传输较大文件时,容易触发内存不足错误。


解决方案

1. 统一流参数类型为TStream

服务端和客户端的方法参数都使用TStream而非具体的TMemoryStream,避免类型不匹配。同时注意:

  • 客户端传递流前,必须将Position重置为0
  • 设置DataSnap参数的FInstanceOwner为False,避免框架自动释放你需要控制的流对象

2. 使用TFileStream替代TMemoryStream

直接通过文件流读写,无需将整个文件加载到内存,从根源减少内存占用。


修改后的代码示例

客户端调用代码(替换原内存流加载逻辑)

LocationID := inireadInt(Files[0],'DATA','LocationID');
BatchName := inireadStr(Files[0],'DATA','BatchNumber');

ImageFile := ChangeFileExt(Files[0],'.img');

// 使用TFileStream直接读取文件,无需加载到内存
var ImageStream: TFileStream;
begin
  ImageStream := TFileStream.Create(ImageFile, fmOpenRead or fmShareDenyWrite);
  try
    ImageStream.Position := 0;
    if FileType = 'BatchTrack' then
    begin
      if Temp.BATCH_TRACK(LocationID,BatchName,ImageStream) = 1 then
      begin
        System.SysUtils.DeleteFile(Files[0]);
      end;
    end;
  finally
    ImageStream.Free;
  end;
end;

客户端BATCH_TRACK方法(调整参数类型与实例所有权)

function TServerMethods1Client.BATCH_TRACK(HeadID: integer; BatchNumber: string;
  Image: TStream): integer;
begin
  if FBATCH_TRACKCommand = nil then
  begin
    FBATCH_TRACKCommand := FDBXConnection.CreateCommand;
    FBATCH_TRACKCommand.CommandType := TDBXCommandTypes.DSServerMethod;
    FBATCH_TRACKCommand.Text := 'TServerMethods1.BATCH_TRACK';
    FBATCH_TRACKCommand.Prepare;
  end;

  FBATCH_TRACKCommand.Parameters[0].Value.SetInt32(HeadID);
  FBATCH_TRACKCommand.Parameters[1].Value.SetWideString(BatchNumber);
  // 设置FInstanceOwner为False,由我们自行管理流的生命周期
  FBATCH_TRACKCommand.Parameters[2].Value.SetStream(Image, False);

  FBATCH_TRACKCommand.ExecuteUpdate;
  Result := FBATCH_TRACKCommand.Parameters[3].Value.GetInt32;
end;

服务端BATCH_TRACK方法(优化流处理,减少内存占用)

function TServerMethods1.BATCH_TRACK(HeadID : integer; Batchnumber : string; Image : TStream) : integer;
var 
  SaveStream: TFileStream;
  SavePath: string;
begin
  Result := -1;
  try
    // 定义保存路径(根据实际需求调整)
    SavePath := '你的服务器保存路径\' + Batchnumber + '_' + IntToStr(HeadID) + '.png';
    SaveStream := TFileStream.Create(SavePath, fmCreate or fmShareDenyWrite);
    try
      // 直接将传入的流写入文件,无需在内存中复制
      SaveStream.CopyFrom(Image, Image.Size);
      Result := 1;
    finally
      SaveStream.Free;
    end;
  except
    // 可添加具体的错误日志记录
    Result := -1;
  end;
end;

额外配置:调整DataSnap最大Blob大小

如果仍存在大文件传输限制,可在客户端和服务端的DataSnap连接参数中添加:

// 客户端连接配置
FDBXConnection.Params.Values['TDBXParameterMetaData.MaxBlobSize'] := '10485760'; // 设置为10MB,按需调整

// 服务端DataSnap服务器配置(在ServerContainer中)
ServerContainer1.SQLConnection1.Params.Values['TDBXParameterMetaData.MaxBlobSize'] := '10485760';

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 18:46:20