Classes单元中一段很有趣的代码

TStream 使用了下面的代码,强制子类必须implement两个seek方法中至少一个

 

首先说明TStream有两个seek方法

function Seek(Offset: Longint; Origin: Word): Longint; overload; virtual; //叫它seek1
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; virtual;//叫它seek2

看看如何实现的

function TStream.Seek(Offset: Longint; Origin: Word): Longint;

  procedure RaiseException;
  begin
    raise EStreamError.CreateResFmt(@sSeekNotImplemented, [Classname]);
  end;

type 

   //声明了一个seek2样式的函数类型
  TSeek64 = function (const Offset: Int64; Origin: TSeekOrigin): Int64 of object;
var 

   //impl是子类的seek2方法,Base是TStream的seek2方法

  Impl: TSeek64;
  Base: TSeek64;
  ClassTStream: TClass;
begin
{ Deflect 32 seek requests to the 64 bit seek, if 64 bit is implemented.
  No existing TStream classes should call this method, since it was originally
  abstract.  Descendent classes MUST implement at least one of either
  the 32 bit or the 64 bit version, and must not call the inherited
  default implementation. } 

//如果进入此函数,说seek1没有被override,下面的任务就是验证seek2必须被override;
  Impl := Seek; //如果子类没有实现seek,那么impl就是seek2的方法(庐山中?)

//下面将ClassTStream将会是TStream的class类型,同时保证当前类是TStream的子类
  ClassTStream := Self.ClassType;
  while (ClassTStream <> nil) and (ClassTStream <> TStream) do
    ClassTStream := ClassTStream.ClassParent;
  if ClassTStream = nil then RaiseException; 

//Base为TStream的seek2方法,这句的语法最有意思
  Base := TStream(@ClassTStream).Seek; 

//开始了,如果当前类的seek2方法和TStream的seek2方法代码相同,那么异常之
  if TMethod(Impl).Code = TMethod(Base).Code then
    RaiseException;

//能执行到这里,表明seek2已经被override了,调用子类实现的seek2方法 
  Result := Seek(Int64(Offset), TSeekOrigin(Origin));
end;

function TStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
{ Default implementation of 64 bit seek is to deflect to existing 32 bit seek.
  Descendents that override 64 bit seek must not call this default implementation. } 

//这里就好解释了,如果执行到这个方法,那么说明本seek2未被override;,那么seek1一定被override了,就调用seek1.
  if (Offset < Low(Longint)) or (Offset > High(Longint)) then
    raise ERangeError.CreateRes(@SRangeError);
  Result := Seek(Longint(Offset), Ord(Origin));
end;

我刚开始看到 时候,还说怎么回事,两个overload的函数互相调用,没有具体代码,原来是要求子类必须实现其中一个,borland的工程师确实很牛!!!

发表于 2004年12月31日 8:56 PM
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是使用 Delphi XE5 编写的对文件夹进行加密的示例代码: ``` uses System.SysUtils, System.Classes, System.IOUtils; procedure EncryptFolder(const SourceFolder, DestFolder, Password: string); var FileName: string; FileStreamIn, FileStreamOut: TFileStream; Buffer: array[0..8191] of Byte; BytesRead, BytesWritten: Integer; begin // Create the destination folder if it doesn't exist TDirectory.CreateDirectory(DestFolder); // Get a list of files in the source folder for FileName in TDirectory.GetFiles(SourceFolder) do begin // Open the input file FileStreamIn := TFileStream.Create(FileName, fmOpenRead); try // Create the output file in the destination folder FileStreamOut := TFileStream.Create(TPath.Combine(DestFolder, TPath.GetFileName(FileName) + '.enc'), fmCreate); try // Write the password to the output file FileStreamOut.WriteBuffer(Password[1], Length(Password)); // Read from the input file and write to the output file, encrypting as we go repeat BytesRead := FileStreamIn.Read(Buffer, SizeOf(Buffer)); if BytesRead > 0 then begin // Encrypt the buffer using a simple XOR cipher for BytesWritten := 0 to BytesRead - 1 do Buffer[BytesWritten] := Buffer[BytesWritten] xor Ord(Password[BytesWritten mod Length(Password) + 1]); FileStreamOut.WriteBuffer(Buffer, BytesRead); end; until BytesRead < SizeOf(Buffer); finally FileStreamOut.Free; end; finally FileStreamIn.Free; end; end; // Get a list of subfolders in the source folder for FileName in TDirectory.GetDirectories(SourceFolder) do begin // Encrypt the subfolder recursively EncryptFolder(FileName, TPath.Combine(DestFolder, TPath.GetFileName(FileName)), Password); end; end; ``` 此函数使用一个简单的 XOR 加密算法对文件进行加密。对于更高级的加密算法,您可能需要使用其他库或工具。请注意,此代码示例仅用于教育和参考目的,实际应用程序应该采用更严格的加密和安全措施。 ### 回答2: 用Delphi XE5可以通过以下代码对文件夹进行加密: 1. 首先,需要引入文件操作的单元:SysUtils、Classes。 2. 创建一个用于加密文件夹的函数EncryptFolder,函数参数为文件夹路径。 3. 在函数内部,首先需要检查文件夹路径是否存在,可以使用函数DirectoryExists来判断。 4. 使用变量Path来保存文件夹路径。 5. 创建一个搜索文件的TSearchRec结构体变量,用于遍历文件夹的所有文件。 6. 使用FindFirst函数来查找文件夹的第一个文件,传入文件夹路径和TSearchRec结构体变量作为参数。 7. 通过循环遍历文件夹的所有文件,直到没有文件为止。 8. 在循环内部,根据文件夹路径和当前搜索到的文件名来构建文件的完整路径。 9. 通过 TFileStream 来打开文件,并以只读的方式读取文件的内容。 10. 将文件内容进行加密,可以使用一些加密算法,例如AES、DES或者Base64来进行加密。 11. 将加密后的内容重新写入文件,可以先创建一个新文件,然后使用 TFileStream 来写入内容。 12. 关闭文件流。 13. 继续使用FindNext函数来搜索下一个文件。 14. 当找到所有文件后,调用FindClose函数来关闭搜索。 以下是一个示例代码: ```pascal procedure EncryptFolder(const FolderPath: string); var Path: string; SearchRec: TSearchRec; FileStream: TFileStream; begin if DirectoryExists(FolderPath) then begin Path := IncludeTrailingPathDelimiter(FolderPath); if FindFirst(Path + '*.*', faAnyFile, SearchRec) = 0 then begin repeat if (SearchRec.Name = '.') or (SearchRec.Name = '..') then Continue; try FileStream := TFileStream.Create(Path + SearchRec.Name, fmOpenRead); try // 进行文件内容加密,例如使用AES算法进行加密 // ... // 创建一个新文件用于写入加密后的内容 FileStream := TFileStream.Create(Path + SearchRec.Name + '.encrypted', fmCreate or fmOpenWrite); try // 将加密后的内容写入新文件 // ... finally FileStream.Free; end; finally FileStream.Free; end; except // 异常处理 end; until FindNext(SearchRec) <> 0; FindClose(SearchRec); end; end; end; ``` 请注意,上述代码只是一个简单的示例,仅对文件夹的所有文件进行了加密处理,实际应用可能需要考虑更多的情况,如文件夹包含子文件夹的处理等。 ### 回答3: 在Delphi XE5,可以使用以下代码对文件夹进行加密: 首先,需要使用IOUtils单元来操作文件夹和文件,使用System.IOUtils单元的TDirectory类和TFile类。 以下是一个示例代码: 1. 使用TDirectory类来获取文件夹下的所有文件,包括子文件夹的文件。 2. 循环遍历文件列表,使用TFile类的Move和Delete方法来对文件进行加密和删除原文件。 ```delphi uses System.IOUtils; // 对文件夹进行加密 procedure EncryptFolder(const AFolder: string); var Files: TStringDynArray; FileItem: string; begin if TDirectory.Exists(AFolder) then begin Files := TDirectory.GetFiles(AFolder, '*.*', TSearchOption.soAllDirectories); for FileItem in Files do begin // 加密文件 TFile.Move(FileItem, FileItem + '.enc'); // 删除原文件 TFile.Delete(FileItem); end; end; end; ``` 使用示例: ```delphi begin // 调用EncryptFolder函数来加密文件夹 EncryptFolder('C:\Path\To\Folder'); end; ``` 上述代码将会遍历指定的文件夹及其子文件夹的所有文件,并将每个文件重命名为原文件名加上`.enc`的后缀,同时删除原文件。这样就实现了对文件夹的加密操作。 请注意,这只是一个简单的示例,实际可能需要更加复杂的加密算法和安全性措施。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值