⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmffile.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 3 页
字号:

begin
   if (FPFileEntries = nil) then
      raise EMMFastFileError.Create(LoadResStr(IDS_FFNOTINIT));

   if (index < Count) then
   begin
      j := 0;
      for i := 0 to FPFileEntryCount^-1 do
      begin
         fe := FPFileEntries[i];
         if not fe.Deleted then
         begin
            if (j = index) then
            begin
               Result := fe.Name;
               exit;
            end;
            inc(j);
         end;
      end;
   end;

   Result := '';
   raise EMMFastFileError.Create(LoadResStr(IDS_FFBADINDEX));
end;

{-- TMMFastFile ---------------------------------------------------------}
function TMMFastFile.GetFilesByName(Name: string): string;
var
   fe: TFileEntry;
   pfe: PFileEntry;

begin
   if (FPFileEntries = nil) then
      raise EMMFastFileError.Create(LoadResStr(IDS_FFNOTINIT));

   if (Name <> '') then
   begin
      fe.Name := PChar(Name);
      pfe := lfind(@fe, FPFileEntries, FPFileEntryCount^, sizeof(TFileEntry), @Compare);
      if (pfe <> nil) then
      begin
         Result := pfe.Name;
      end;
   end
   else
   begin
      Result := '';
      raise EMMFastFileError.Create(LoadResStr(IDS_FFBADFILENAME));
   end;
end;

{-- TMMFastFile ---------------------------------------------------------}
procedure TMMFastFile.CreateFastFile(FileName: TFileName; nMaxFiles: integer);
var
   hOut: integer;
   pfe: PFileEntryArray;
   Tmp: Longint;

begin
   if FileName = '' then exit;

   hOut := FileCreate(FileName);
   if (hOut < 0) then
      raise EMMFastFileError.CreateFmt(LoadResStr(IDS_FFCREATEERROR),['FastFile']);

   try
      inc(nMaxFiles); // make place for one entry more
      pfe := nil;
      pfe := GlobalAllocMem(nMaxFiles * sizeOf(TFileEntry));
      FillChar(pfe^, nMaxFiles * sizeOf(TFileEntry), 0);

      FileName := ExpandUNCFileName(FileName);

      if FileWrite(hOut, KENNUNG, sizeOf(KENNUNG)-1) <> sizeOf(KENNUNG)-1 then
         raise EMMFastFileError.Create(LoadResStr(IDS_FFWRITEERROR));

      // write the number of max directory entries
      Tmp := nMaxFiles-1;
      if FileWrite(hOut, Tmp, sizeOf(Tmp)) <> sizeOf(Tmp) then
         raise EMMFastFileError.Create(LoadResStr(IDS_FFWRITEERROR));

      // write the number of current directory entries (0)
      Tmp := 0;
      if FileWrite(hOut, Tmp, sizeOf(Tmp)) <> sizeOf(Tmp) then
         raise EMMFastFileError.Create(LoadResStr(IDS_FFWRITEERROR));

     {$IFDEF TRIAL}
     {$DEFINE _HACK1}
     {$I MMHACK.INC}
     {$ENDIF}

      // set the offset for the first entry
      pfe[0].Offset := (sizeOf(KENNUNG)-1+2*sizeOf(Longint)) + nMaxFiles * sizeOF(TFileEntry);

      if FileWrite(hOut, pfe^, nMaxFiles * sizeOf(TFileEntry)) <> nMaxFiles * sizeOf(TFileEntry) then
         raise EMMFastFileError.Create(LoadResStr(IDS_FFWRITEERROR));

   finally
      SysUtils.FileClose(hOut);
      GlobalFreeMem(Pointer(pfe));
   end;
end;

{-- TMMFastFile ---------------------------------------------------------}
procedure TMMFastFile.Init;
begin
   if (FFileName = '') or not SysUtils.FileExists(FFileName) then
      raise EMMFastFileError.Create(LoadResStr(IDS_FFBADFILENAME));

   // make sure any old FastFile is closed
   Done;

   try
      // get a file handle array
      ReAllocMem(FPFileHandles, FMaxHandles*SizeOf(TFileHandle));
      if (FPFileHandles = nil) then OutOfMemoryError;

      FillChar(FPFileHandles^, FMaxHandles * sizeOf(TFileHandle), 0);

      // create a memory mapped file for the master file
      FHFile := CreateFile(PChar(FFileName), GENERIC_READ or GENERIC_WRITE,
                           FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
                           OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0);

      if (FHFile = 0) or (FHFile = HFILE_ERROR) then
      begin
         FHFile := 0;
         raise EMMFastFileError.Create('CreateFile failed with Error Code: '+IntToStr(GetLastError));
      end;

      FHFileMapping := CreateFileMapping(FHFile,nil,PAGE_READWRITE,0,0,nil);
      if (FHFileMapping = 0) then
         raise EMMFastFileError.Create('CreateFileMapping failed with Error Code: '+IntToStr(GetLastError));

      FPBase := MapViewOfFile(FHFileMapping, FILE_MAP_WRITE, 0, 0, 0);
      if (FPBase = nil) then
         raise EMMFastFileError.Create('MapViewOfFile failed with Error Code: '+IntToStr(GetLastError));

      // get initial data from the memory mapped file
      FMaxFiles := PLongint(FPBase+sizeOf(KENNUNG)-1)^;
      FPFileEntryCount := PLongint(FPBase + sizeOf(KENNUNG)-1 + sizeOf(Longint));
      FPFileEntries := PFileEntryArray(FPBase + sizeOf(KENNUNG)-1 + 2*sizeOf(Longint));

   except
      Done;
      raise;
   end;
end;

{-- TMMFastFile ---------------------------------------------------------}
procedure TMMFastFile.UpdateFastFile(Size: integer);
begin
   try
      if (FHFileMapping <> 0) then
      begin
         if (FPBase <> nil) then
         begin
            UnmapViewOfFile(FPBase);
            FPBase := nil;
         end;
         CloseHandle(FHFileMapping);
         FHFileMapping := 0;
      end;

      if (FHFile <> 0) then
      FHFileMapping := CreateFileMapping(FHFile,nil,PAGE_READWRITE,0,Size,nil);
      if (FHFileMapping = 0) then
         raise EMMFastFileError.Create('CreateFileMapping failed with Error Code: '+IntToStr(GetLastError));

      FPBase := MapViewOfFile(FHFileMapping, FILE_MAP_WRITE, 0, 0, 0);
      if (FPBase = nil) then
         raise EMMFastFileError.Create('MapViewOfFile failed with Error Code: '+IntToStr(GetLastError));

      // get initial data from the memory mapped file
      FMaxFiles := PLongint(FPBase+sizeOf(KENNUNG)-1)^;
      FPFileEntryCount := PLongint(FPBase + sizeOf(KENNUNG)-1 + sizeOf(Longint));
      FPFileEntries := PFileEntryArray(FPBase + sizeOf(KENNUNG)-1 + 2*sizeOf(Longint));

      {$IFDEF TRIAL}
      {$DEFINE _HACK2}
      {$I MMHACK.INC}
      {$ENDIF}

      HandlesLost;

   except
      Done;
      raise;
   end;
end;

{-- TMMFastFile ---------------------------------------------------------}
procedure TMMFastFile.Done;
begin
   Pack;
   if (FHFileMapping <> 0) then
   begin
      if (FPBase <> nil) then UnmapViewOfFile(FPBase);
      CloseHandle(FHFileMapping);
      FHFileMapping := 0;
   end;
   if (FHFile <> 0) then
   begin
      CloseHandle(FHFile);
      FHFile := 0;
   end;
   if (FPFileHandles <> nil) then
   begin
      ReAllocmem(FPFileHandles,0);
      FPFileHandles := nil;
   end;
   FPBase := nil;
   FPFileEntryCount := nil;
   FPFileEntries := nil;
end;

{-- TMMFastFile ---------------------------------------------------------}
function TMMFastFile.AddFile(const Name: TFileName): TFileName;
var
   hIn      : THandle;
   Bytes,pos: integer;
   Buffer   : PChar;
   NewName  : String;

begin
   Result := '';

    if (FPFileEntries = nil) then
       raise EMMFastFileError.Create(LoadResStr(IDS_FFNOTINIT));

   hIn  := 0;
   Buffer := nil;

   try
      // is place for more entry's ?
      if (FPFileEntryCount^ >= FMaxFiles) then
         raise EMMFastFileError.Create(LoadResStr(IDS_FFDIRFULL));

      // get a short filename for the new file
      NewName := GetShortFileName(Name);
      if (NewName = '') then
         raise EMMFastFileError.Create(LoadResStr(IDS_FFBADFILENAME));

      // is the file already in directory or deleted ?
      if FileExists(NewName) then
         raise EMMFastFileError.Create(LoadResStr(IDS_FFDUPLICATEFILENAME));

      // open the new file
      hIn := SysUtils.FileOpen(Name, fmOpenRead);
      if (hIn < 0) then
         raise EMMFastFileError.Create(LoadResStr(IDS_FFOPENERROR));

      Buffer := GlobalAllocMem(BLOCK_SIZE);

      // adjust the size for the MemMapFile
      UpdateFastFile(FPFileEntries[FPFileEntryCount^].Offset+ GetFileSize(Name));

      pos := FPFileEntries[FPFileEntryCount^].Offset;
      while True do
      begin
         Bytes := SysUtils.FileRead(hIn, Buffer^, BLOCK_SIZE);
         if (Bytes = 0) then break;
         if (Bytes < 0) then
            raise EMMFastFileError.Create(LoadResStr(IDS_FFREADERROR));

         try
            move(Buffer^, (FPBase + pos)^, Bytes);
            inc(pos, Bytes);
         except
            raise EMMFastFileError.Create(LoadResStr(IDS_FFWRITEERROR));
         end;

         if (Bytes < BLOCK_SIZE) then break;
      end;

      FPFileEntries[FPFileEntryCount^].Name := NewName;
      FPFileEntries[FPFileEntryCount^].Deleted := False;
      FPFileEntries[FPFileEntryCount^].Size := pos - FPFileEntries[FPFileEntryCount^].Offset;

      // inc the directory entry counter
      inc(FPFileEntryCount^);
      // save current file position for the next entry
      FPFileEntries[FPFileEntryCount^].Offset := pos;

      Result := NewName;
      Change;

   finally
      SysUtils.FileClose(hIn);
      GlobalFreeMem(Pointer(Buffer));
   end;
end;

{-- TMMFastFile ---------------------------------------------------------}
procedure TMMFastFile.RemoveFile(const Name: TFileName);
var
   fe : TFileEntry;
   pfe: PFileEntry;
   i  : integer;

begin
    if (FPFileEntries = nil) then
       raise EMMFastFileError.Create(LoadResStr(IDS_FFNOTINIT));

    if (Name = '') then
       raise EMMFastFileError.Create(LoadResStr(IDS_FFBADFILENAME));

    fe.Name := Name;
    pfe := lfind(@fe, FPFileEntries, FPFileEntryCount^, sizeof(TFileEntry), @Compare);
    if (pfe <> nil) then
    begin
       for i := 0 to FMaxHandles-1 do
       begin
          if (FPFileHandles[i].pfe <> nil) and
             (FPFileHandles[i].pfe.Name = pfe.Name) then
          begin
             FPFileHandles[i].inUse := False;
             break;
          end;
       end;
       pfe.Deleted := True;
       inc(FNumDeleted);
       Change;
    end
    else raise EMMFastFileError.CreateFmt(LoadResStr(IDS_FFNOTFOUND),[Name]);
end;

{-- TMMFastFile ---------------------------------------------------------}
procedure TMMFastFile.RenameFile(const OldName, NewName: TFileName);
var

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -