我正在尝试编写一个Delphi控制台应用程序,为其标准输入创建一个TStream,为其标准输出创建另一个TStream.
(它将由主机应用程序启动,其输入和输出重定向到管道,并将二进制数据传入/传出该主机应用程序,因此TStream将比ReadLn/WriteLn更适合于该任务.)
如何在标准输入或标准输出上打开TStream?
我需要扩展TFileStream,以便它可以使用不是0偏移量的文件,而是来自用户定义的偏移量.我的意思是它必须将用户定义的偏移解释为流开始.我的代码是:
type
TSuFileStream = class(TFileStream)
protected
FOffset : int64;
procedure SetOffset(Offset : int64);
procedure SetSize(NewSize: Longint); override;
procedure SetSize(const NewSize: Int64); override;
public
constructor Create(const AFileName: string; Mode: Word); overload;
constructor Create(const AFileName: string; Mode: Word; Rights: Cardinal); overload;
function Seek(Offset: Longint; Origin: Word): Longint; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
property Offset : int64 read FOffset write SetOffset;
end;
...
constructor TSuFileStream.Create(const AFileName: string; Mode: Word);
begin
inherited Create(AFileName, Mode);
FOffset := 0;
end;
constructor TSuFileStream.Create(const …Run Code Online (Sandbox Code Playgroud) 我正在尝试将字符串转换为TStream.我的下面的代码在CopyFrom行上给我一个"抽象错误"消息.我在这里碰壁砖,有关如何解决这个问题的想法吗?
procedure StringToStream(const AString: string; out AStream: TStream);
var
SS: TStringStream;
begin
SS := TStringStream.Create(AString);
try
SS.Position := 0;
AStream.CopyFrom(SS, SS.Size); //This is where the "Abstract Error" gets thrown
finally
SS.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud) 我为旧版RADStudio提供了一些派生类,只需重新实现Read,Write,Seek方法以及Size和Position属性.
我希望将这些移植到XE3,但我看到现在(例如)有三个重载Read- 原始的一个,加上两个以TBytes作为参数.
德尔福
function Read(var Buffer; Count: Longint): Longint; overload; virtual;
function Read(Buffer: TBytes; Offset, Count: Longint): Longint; overload; virtual;
function Read(var Buffer: TBytes; Count: Longint): Longint; overload;
Run Code Online (Sandbox Code Playgroud)
C++
virtual int __fastcall Read(void *Buffer, int Count)/* overload */;
virtual int __fastcall Read(System::DynamicArray<System::Byte> Buffer, int Offset, int Count)/* overload */;
int __fastcall Read(System::DynamicArray<System::Byte> &Buffer, int Count)/* overload */;
Run Code Online (Sandbox Code Playgroud)
我需要实现这三个,还是只需一个?如果只有一个,哪一个......?
通常情况下,我可以从VCL源代码中找到它,但我目前只有试用版(无源代码).
我已将文件复制到Windows剪贴板中(只需单击右键,复制).我想加载一个TStream后代与当前存储在剪贴板中的文件.
uses
Classes, Clipbrd;
MyStream := TMemoryStream.Create;
try
//here I would like to load the clipboard file into MyStream
finally
MyStream.Free;
end;
Run Code Online (Sandbox Code Playgroud) 我有一个继承自TFileStream的类和一个继承自TMemoryStream的类.两者都实现与读取数据完全相同的功能,例如:
TCustomFileStream = class (TFileStream)
function ReadByte: byte;
function ReadWord: word;
function ReadWordBE: word;
function ReadDWord: longword;
function ReadDWordBE: longword;
function ReadString(Length: integer): string;
function ReadBlockName: string;
etc
Run Code Online (Sandbox Code Playgroud)
当我想编写一个可以将任何类型的流作为参数的函数时,我必须使用TStream:
function DoStuff(SourceStream: TStream);
Run Code Online (Sandbox Code Playgroud)
这当然意味着我无法使用自定义功能.什么是解决这个问题的最好方法?理想情况下,我希望能够有一个兼容FileStream或MemoryStream的Tstream兼容类,所以我可以做这样的事情,如果流是FileStream或MemoryStream则无关紧要:
function DoStuff(SourceStream: TMyCustomStream);
begin
data := SourceStream.ReadDWord;
otherData := SourceStream.Read(Buffer, 20);
end;
Run Code Online (Sandbox Code Playgroud) 我是Delphi的新手.在TStrem类的文档中,我读到它是一个抽象类.所以我认为当我尝试使用时,编译器会出错
stream := TStream.Create();
Run Code Online (Sandbox Code Playgroud)
为什么不?
我有以下代码片段
Procedure TFrm.Retrieve(mystring : string);
var
bs : TStream;
...
begin
...
bs:=nil;
//bs:= TStream.create;
try
bs := CreateBlobStream(FieldByName('Picture'), bmRead);
finally
bs.Free;
end;
...
end;
Run Code Online (Sandbox Code Playgroud)
我在理解bs变量的初始化时遇到了问题.
如果我不初始化它,我得到一个明显的警告.
Variable 'bs' might not have been initialized.
Run Code Online (Sandbox Code Playgroud)
现在,如果我作为评论部分,即
bs:= TStream.create;
Run Code Online (Sandbox Code Playgroud)
我收到以下警告.
Constructing instance of 'TStream' containing abstract method 'TStream.Read'
Constructing instance of 'TStream' containing abstract method 'TStream.Write'
Run Code Online (Sandbox Code Playgroud)
最后,如果我使用它,它的工作完全正常
bs:=nil;
Run Code Online (Sandbox Code Playgroud)
我是通过分配来做到的 Nil吗?
任何观点赞赏.
在Delphi程序中,我有一个包含4,000,000,001个红衣主教的动态数组.我正在尝试写(后来读)它做了一个驱动器.我使用了以下内容:
const Billion = 1000000000;
stream := tFileStream.Create( 'f:\data\BigList.data', fmCreate);
stream.WriteBuffer( Pointer( BigArray)^, (4 * billion + 1) * SizeOf( cardinal));
stream.free;
Run Code Online (Sandbox Code Playgroud)
它轰炸了:...引发异常类EWriteError,消息'Stream write error'.
它写的文件大小只有3,042,089KB.
难道我做错了什么?一次可写的大小是否有限制(约3GB)?
我已经从 Delphi 6 迁移到 Delphi 11(64 位版本),并且我正在使用 Indy 和 ZLib 组件。我已经从 Indy 9 迁移到 Indy 10,使用组件发布 API,在此之前我通过以下方式将字符串写入流:
var
XML: String;
stream: TStream;
begin
...
stream.WriteBuffer(XML[1], Length(XML) * 2);
Run Code Online (Sandbox Code Playgroud)
然后使用 ZLib 组件对其进行压缩。但当它到达服务器时,它会包含消息中每个字母的空格:
Run Code Online (Sandbox Code Playgroud)< h t m l > u s e r < / h t m l >
关于如何解决这个问题有什么想法吗?