Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Problem with creating an empty/blank file above 1.16GB

Posted on 2011-09-28
1
Medium Priority
?
453 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
1 Comment
 
LVL 25

Accepted Solution

by:
epasquier earned 2000 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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

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…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
Suggested Courses

715 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