zoukankan      html  css  js  c++  java
  • ReadFileToBuffer

    function ReadFileToBuffer(const AFileName: string; var AFileSize: Cardinal; var AData): Boolean;
    var
    FileHandle: THandle;
    MappingHandle: THandle;
    FindData: TWin32FindData;
    MappingName: string;
    TheCreationTime: TFileTime;
    FileAttrs: DWORD;
    ThisSize: Cardinal;
    CommitSize: Cardinal;
    Segment: Cardinal;
    PFileData, PDest: Pointer;

    procedure ReleaseMemory;
    begin
        Windows.VirtualFree(PDest, 0, MEM_RELEASE);
        PPointer(@AData)^ := nil;
        AFileSize := 0;
    end;

    function MoveDataTo(ASource, ADest: Pointer; ASize: Cardinal): Boolean;
    begin
        Result := False;
        try
          CriticalSectionLock;
          try
            Windows.VirtualAlloc(PFileData, CommitSize, MEM_COMMIT, PAGE_READONLY);
            Windows.VirtualLock(PFileData, CommitSize);
            System.Move(ASource^, ADest^, ASize);
          finally
            Windows.VirtualUnlock(PFileData, CommitSize);
            Windows.VirtualFree(PFileData, CommitSize, MEM_DECOMMIT);
            CriticalSectionUnlock;
          end;
        except
          on EAccessViolation do
          begin
            Windows.VirtualUnlock(PFileData, CommitSize);
            Windows.VirtualFree(PFileData, CommitSize, MEM_DECOMMIT);
            CriticalSectionUnlock;
            ReleaseMemory;
            Exit;
          end;
        end;
        Result := True;
    end;

    begin
    Result := False;
    AFileSize := 0;
    FileHandle := Windows.FindFirstFile(PChar(AFileName), FindData);
    if FileHandle = INVALID_HANDLE_VALUE then Exit;
    ThisSize := FindData.nFileSizeLow;
    Windows.FindClose(FileHandle);

    FileAttrs := Windows.GetFileAttributes(PChar(AFileName));
    if (FileAttrs and FILE_ATTRIBUTE_READONLY) <> 0 then
    begin
        if not Windows.SetFileAttributes(PChar(AFileName), FileAttrs xor

    FILE_ATTRIBUTE_READONLY) then Exit;
    end;

    if ThisSize = 0 then
    begin
        Windows.DeleteFile(PChar(AFileName));
        Exit;
    end;

    try
        PDest := nil;
        PDest := Windows.VirtualAlloc(nil, ThisSize, MEM_COMMIT or MEM_RESERVE,

    PAGE_READWRITE);

        PFileData := nil;
        AFileSize := ThisSize;
        PPointer(@AData)^ := PDest;

        CommitSize := 0;
        while CommitSize < AFileSize do
        begin
          PByte(PDest)^ := 0;
          PDest := Pointer(DWORD(PDest) + $00001000);
          Inc(CommitSize, $00001000);
        end;
        PDest := PPointer(@AData)^;

        try
          FileHandle := Windows.CreateFile(PChar(AFileName), Const_FileAccess,

    Const_FileShare, nil, OPEN_EXISTING, 0, 0);
          if FileHandle = INVALID_HANDLE_VALUE then
          begin
            ReleaseMemory;
            Exit;
          end;

          TheCreationTime := FindData.ftCreationTime;
          MappingName := GetFileNameExcludeExt(AFileName) + Format('_%.8x%.8x',

    [TheCreationTime.dwHighDateTime, TheCreationTime.dwLowDateTime]);
          MappingHandle := Windows.OpenFileMapping(FILE_MAP_ALL_ACCESS, False, PChar

    (MappingName));
          if not MappingHandle <> 0 then
          begin
            MappingHandle := Windows.CreateFileMapping(FileHandle, nil, PAGE_READWRITE or

    SEC_RESERVE, 0, ThisSize, PChar(MappingName));
            if (MappingHandle = 0) or (Windows.GetLastError <> ERROR_SUCCESS) then
            begin
              ReleaseMemory;
              Exit;
            end;
          end;

          Segment := 0;
          while ThisSize <> 0 do
          begin
            if ThisSize and $FFFF0000 > 0 then
            begin
              PFileData := Windows.MapViewOfFile(MappingHandle, FILE_MAP_ALL_ACCESS, 0,

    Segment, $00010000);
              if PFileData = nil then
              begin
                ReleaseMemory;
                Exit;
              end;
              if not MoveDataTo(PFileData, PDest, $00010000) then Exit;
              Windows.UnmapViewOfFile(PFileData);
              PDest := Pointer(DWORD(PDest) + $00010000);
              Segment := ((Segment shr 16) + 1) shl 16;
              Dec(ThisSize, $00010000);
            end
            else
            begin
              PFileData := Windows.MapViewOfFile(MappingHandle, FILE_MAP_ALL_ACCESS, 0,

    Segment, ThisSize);
              if PFileData = nil then
              begin
                ReleaseMemory;
                Exit;
              end;
              if not MoveDataTo(PFileData, PDest, ThisSize) then Exit;
              Windows.UnmapViewOfFile(PFileData);
              Dec(ThisSize, ThisSize);
            end;
          end;

          PFileData := nil;
          Result := True;
        finally
          if PFileData <> nil then Windows.UnmapViewOfFile(PFileData);
          if MappingHandle <> 0 then Windows.CloseHandle(MappingHandle);
          if FileHandle <> INVALID_HANDLE_VALUE then Windows.CloseHandle(FileHandle);
        end;
    except
        on Exception do
        begin
          if PFileData <> nil then Windows.UnmapViewOfFile(PFileData);
          if MappingHandle <> 0 then Windows.CloseHandle(MappingHandle);
          if FileHandle <> INVALID_HANDLE_VALUE then Windows.CloseHandle(FileHandle);
          ReleaseMemory;
          Exit;
        end
    end;
    end;

  • 相关阅读:
    c#发送邮件
    时间戳转换成时间js(年-月-日,例如“2017-04-22”)
    c# 如何读取web.config中的内容(ConfigurationManager)
    fiddler抓包软件的使用--请求头--ajax
    c#之双色球
    天干地支象法
    php之属性重载和方法重载
    c#之线程随机
    C#之参数线程
    c#线程创建
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2940624.html
Copyright © 2011-2022 走看看