【问题标题】:delphi Drag and drop stream memory over 1GBdelphi 拖放流内​​存超过 1GB
【发布时间】:2011-11-12 06:34:51
【问题描述】:

我有严重的问题,我被困在这个问题上:( 我需要从我的应用程序大文件(有时超过 1GB)传输到另一个应用程序,即 TotalCommander 或 Explorer。 为此,我需要从源文件读取部分文件到流,处理它并保存到输出流。 我无法加载我需要读取大约 1-30MB 的整个文件,处理并保存。 我正在为 Delphi 7 使用 Drag Drop 组件套件

示例代码(绝望中我尝试了许多变体):

Var
 F13Stream : TmemoryStream;

Procedure Process_Data;
Var
 FileIn : TFileStream;
begin
 FileIn := TFileStream.Create('c:\SampleData.dat', fmOpenRead);
 Repeat
 ..read from FileIn, process data
 ..save to F13Stream
 ..write F13Stream to output? and free memory to next part data//Sorry i have no idea what to doit :(
 Until eof(source_file);
 FileIn.Free;
end;

procedure TForm13.OnGetStream(Sender: TFileContentsStreamOnDemandClipboardFormat;
  Index: integer; out AStream: IStream);
begin
 Form13.F13Stream := TMemorystream.Create;
 Process_Data;
 try
  AStream := nil;
  AStream := TFixedStreamAdapter.Create(F13Stream, soOwned);
 except
  F13Stream.Free;
  raise;
 end;
end;

procedure TForm13.LMDShellList1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 TVirtualFileStreamDataFormat(DataFormatAdapterSource.DataFormat).FileNames.Clear;
 TVirtualFileStreamDataFormat(DataFormatAdapterSource.DataFormat).FileNames.Add('TestFile');
 DropEmptySource1.Execute;
end;

这是我尝试做的例子。也许另一个组件/代码会这样做,没有问题。 我可以复制没有大小限制的文件,但我需要部分处理大文件并部分通过内存作为流/数组发送到另一个应用程序,而不是使用临时磁盘驱动器内存。 感谢您的帮助。

更新:

procedure TForm13.OnGetStream(Sender: TFileContentsStreamOnDemandClipboardFormat;
  Index: integer; out AStream: IStream);
var
 plk1 : TFileStream;
 buff : array[0..65535] of byte;
 read : Longint;
begin
 AStream := nil;
 Form13.F13Stream := TMemoryStream.Create;
 AStream := TFixedStreamAdapter.Create(Form13.F13Stream, soOwned);
 plk1 := TFileStream.Create('h:\Sample2GB_file.dat', fmOpenRead);
 repeat
  read := plk1.Read(buff, 65536);
  AStream.Write(@buff, read, PLongint(65536));
  AStream.SetSize(0);
 until read <> 65536;
 plk1.Free;
end;

它也不起作用。结果我有 0 字节的文件输出。

更新 2:

如果我删除行:“AStream.SetSize(0);”然后我有“内存不足”错误。

【问题讨论】:

  • 我完全不明白这个问题。
  • @David Heffernan 我需要将文件从我的应用程序中拖放到另一个应用程序中。大小超过 1GB 的文件,我需要对其进行处理(解密)。
  • 您需要花一些时间来清理它。准确解释你卡在哪里。我在这里看不到任何解密。我看不出什么不起作用。
  • 我认为他正在尝试 (OLE) 将虚拟文件从他的应用程序拖放到资源管理器(总指挥官)。就像在您的应用程序中拾取某些东西,将其拖出并让资源管理器知道文件可用,但您仅在实际删除数据时才 IStream 数据。在将输入数据提供给 OLE 时,他似乎需要一种方法来分块处理输入数据……
  • 但你没有问这个。这个问题被各种令人困惑的细节所笼罩。您需要立即退后一步,了解您拥有的最基本的拖放示例。然后从那里一步一步地工作,一次添加一个功能。这是我最好的建议。

标签: delphi memory drag-and-drop stream data-transfer


【解决方案1】:

您实际上无法在 OnGetStream 中写入 AStream。它是您需要设置的 IStream,接收器(发生丢弃的地方)将从中读取您的数据。如果您需要处理源文件,请在拖动开始之前执行此操作并将结果保存在另一个文件中。然后只需将您的新文件配置为拖动源。您可以在 Mouse Down 事件中简单地执行此操作,或者如果您更喜欢使用虚拟方法,请在 OnGetStream 事件中执行:

procedure TForm13.OnGetStream(Sender: TFileContentsStreamOnDemandClipboardFormat;
  Index: integer; out AStream: IStream);
var
 plk1 : TFileStream;
begin
 AStream := nil;
 // TODO: Create the file to stream (read your source and save it to new_source.dat after your processing)
 plk1 := TFileStream.Create('h:\new_source.dat', fmOpenRead);
 AStream := TFixedStreamAdapter.Create(plk1, soOwned);
end;

您还可以创建自己的 TStream 类,在 Read 方法中即时读取、处理和返回数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多