Solved

Problem with creating an empty/blank file above 1.16GB

Posted on 2011-09-28
1
444 Views
Last Modified: 2016-09-29
So, i'm trying to create a file that is... lets say 2GB, but when i use the routine i wrote, the file is 1.16GB, how do i avoid this limit ?


procedure TDAPClass.CreateBlankFile(
const FilePath: String );
const
  TmpFileBuffer : Byte = ($00);
  dwFlagsAndAttr = FILE_FLAG_RANDOM_ACCESS;
var
  hTmpFile      : THandle;
  nBytesWritten : DWORD;
  I             : Integer;
begin
  // Create a temp blank file
  hTmpFile := CreateFile(
  PChar( FilePath ),
  GENERIC_WRITE,
  0,
  nil,
  CREATE_ALWAYS,
  FILE_ATTRIBUTE_TEMPORARY or dwFlagsAndAttr,
  0 );
  for I := 0 to Pred(nConnections) do
  begin
    // seek to given offset
    SetFilePointer(
     hTmpFile, i64EndOffset[I] - 1, nil, FILE_BEGIN );
    Sleep(500);
    // Write 1 byte in current offset
    WriteFile(
     hTmpFile, TmpFileBuffer, SizeOf(TmpFileBuffer), nBytesWritten, nil );
    Sleep(500);
  end;
  // Close Temp file handle
  CloseHandle( hTmpFile );
end;

Open in new window

0
Comment
Question by:rotem156
1 Comment
 
LVL 25

Accepted Solution

by:
epasquier earned 500 total points
ID: 36890614
SetFilePointer has a weird way of managing size parameters. It takes the size in 2 different ways :
- movement is a signed 32 bits integer, in first parameter after handle, second param not used (=nil) :
=> MAX = 2GB -1 .
So this method will fail if you try to put unsigned size equal or above 2GB.
- movement is a signed 64 bits integer : first param takes the low order part, and second parameter takes a pointer to the highest order part. That is the weird part, the pointer. See how I managed it in code.

You will ask as myself first did : why so complex ? why a pointer in 2nd parameter ? well, because if this was not a pointer, seeing that they made a single function with 2 functioning modes, you would have problem with 64 bits sizes between $80000000 (2GB) and $FFFFFFFF (4GB-1) because then high order part would be nul, AND first part would have to be considered SIGNED, not UNSIGNED.

Of course, they could have replaced all that with a single 64 bits signed value, even if that meant separate that in 2 params, but without pointer stuff and 2 functioning modes. But that would have broken existing 32bits only code using the API.

One last note : Delphi Seek & Truncate functions, which would be the equivalent of the method used below, have the same restriction with the 2GB-1 limit, or you'll end up with I/O error #131 :  ERROR_NEGATIVE_SEEK

Here is how to do that properly :

procedure CreateBlankFile(const FilePath: String; Size:int64 );
Var
 hTmpFile:THandle;
const
 dwFlagsAndAttr = FILE_FLAG_RANDOM_ACCESS;
begin
 hTmpFile := CreateFile( PChar( FilePath ),
  GENERIC_WRITE, 0, nil, CREATE_ALWAYS,
  FILE_ATTRIBUTE_TEMPORARY or dwFlagsAndAttr, 0 );
 try
  if Size>=$80000000
   Then SetFilePointer( hTmpFile, Size {And $FFFFFFFF}, Pointer(Cardinal(@Size)+4), FILE_BEGIN )
   Else SetFilePointer( hTmpFile, Size, nil, FILE_BEGIN );
  SetEndOfFile( hTmpFile );
 finally
  CloseHandle( hTmpFile );
 end;
end;

Open in new window

0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question