Delphi中的增量指针/从指针创建流

Delphi中的增量指针/从指针创建流,delphi,pointers,Delphi,Pointers,缩写:是否可以从指针创建流 我有一个指针,指向我需要读取的文件数据。我使用WriteBuffer()将数据从指针传输到一个TFileStream,它可以工作。但现在我想逐块阅读,以显示进度条。所以我需要一步一步地读 我必须选择: 1) 增加指针Buff,并像往常一样使用WriteBuffer()。(WriteBuffer总是从头开始读取,因此我需要增加指针) 2) 从指针创建一个流。这可能吗 代码: 您可以创建自己的TCustomMemoryStream子体,它使用从GetOverlay()接收

缩写:是否可以从指针创建流

我有一个指针,指向我需要读取的文件数据。我使用WriteBuffer()将数据从指针传输到一个TFileStream,它可以工作。但现在我想逐块阅读,以显示进度条。所以我需要一步一步地读

我必须选择:

1) 增加指针Buff,并像往常一样使用WriteBuffer()。(WriteBuffer总是从头开始读取,因此我需要增加指针)

2) 从指针创建一个流。这可能吗

代码:


您可以创建自己的
TCustomMemoryStream
子体,它使用从
GetOverlay()
接收的地址和大小在构造函数中调用
SetPointer()
。有关更多信息,请参阅
TCustomMemoryStream
的Delphi文档

编辑:

好吧,这与你的问题无关,但是在你写的评论中,你只希望通过流从正在运行的可执行文件中读取。这很容易做到:

procedure TForm1.Button1Click(Sender: TObject);
var
  Str: TStream;
begin
  Str := TFileStream.Create(ParamStr(0), fmOpenRead or fmShareDenyNone);
  try
    Caption := Format('Size of executable: %u bytes', [Str.Size]);
    // start to read the contents of the file ...

  finally
    Str.Free;
  end;
end;

我将保留原始答案,以防有人真的想从指向内存块的指针创建(只读)流。

当我阅读您的问题时,我会想到一个问题。您有一个指向文件数据的指针(我想是从磁盘来的吧?),您正在用该指针的数据填充一个文件流(尽管在您的问题中,您是在填充一个memorystream)。为什么不使用TFileStream打开正在读取的文件

var
  FileStream: TFileStream;
  Header: TOCHeader;
begin
  FileStream := TFileStream.Create('c:\fileIWantToRead.txt', fmOpenRead);
  FileStream.ReadBuffer(Header, SizeOf(Header));
  <...>
end;

TResourceStream在这里可以…

您的代码中有两个InputStream变量。你们俩都在读,也在写。你能澄清一下吗?哦,对不起。我已经修好了。我只是复制了重要的变量和代码短语,InputStream定义似乎非常重要;-)。请注意,您需要在写入流和读取流之间重置流的位置。您当前的代码会引发异常。是的,我知道。但我会将其添加到源代码中,以避免混淆其他代码。谢谢,非常感谢。我无法使用TFileStream,因为我想从当前正在运行的EXE中读取数据以创建自解压文件。您建议的解决方案已编译,我将在它开始工作时将其标记为已接受的答案;-)。正如您在mghie的帖子中所看到的,TFileStream不限于“c:\FileIwantRead.txt”;),你也可以用它打开你的exe。当我开始执行我的程序时,我试过了,但我得到了一个错误,文件当前正在使用,所以我认为这是不可能的。。。你试过了吗?是的,我确实试过。如果您在访问文件时遇到问题,请尝试使用SysInternals工具,该工具可以向您显示文件是以独占方式打开的。我希望您没有误解我的问题:我必须读取当前正在运行的exe,应用程序必须读取自身以从自身提取资源。(类似于SFX存档…)TFileStream是使用ParamStr(0)作为文件名创建的,表示当前正在运行的应用程序。这不是您需要做的吗?如果您需要从当前运行的EXE中读取资源,为什么不使用Delphi的内置支持呢?创建一个TResourceStream并将HInstance(当前应用的句柄)作为第一个参数传递给构造函数。。。
var
  FileStream: TFileStream;
  Header: TOCHeader;
begin
  FileStream := TFileStream.Create('c:\fileIWantToRead.txt', fmOpenRead);
  FileStream.ReadBuffer(Header, SizeOf(Header));
  <...>
end;
Inc(PByte(Buff), SizeOf(TOC)); //sizeof returns size in bytes, so cast pointer to a bytepointer