Board index » cppbuilder » Create an empty file

Create an empty file


2007-11-03 07:27:41 AM
cppbuilder29
How do you go about in creating an empty file lets say about
1MB in size?
I am trying to learn how to use two threads to write to a file,
but my{*word*128}step is creating the empty file first, then writing to
the file afterwards.
The programs that I have seen do this is download managers,
and torrent programs.
TIA
CJ
 
 

Re:Create an empty file

All of these are Win32 API functions, not VCL.
CallCreateFile to create the file.
Call SetFilePointer to seek to the size wanted.
Call SetEndOfFile to set this as the end.
Call CloseHandle to close the file.
If I remember correctly, the limit on file size with this is 2Gig - 2 bytes.
. Ed
Quote
CJ wrote in message
news:472bb268$ XXXX@XXXXX.COM ...

How do you go about in creating an empty file lets say about
1MB in size?

I am trying to learn how to use two threads to write to a file,
but my{*word*128}step is creating the empty file first, then writing to
the file afterwards.

The programs that I have seen do this is download managers,
and torrent programs.
 

Re:Create an empty file

Thank you very much
"Ed Mulroy [TeamB]" < XXXX@XXXXX.COM >wrote in message
Quote
All of these are Win32 API functions, not VCL.
 

{smallsort}

Re:Create an empty file

"CJ" < XXXX@XXXXX.COM >wrote in message
Quote
How do you go about in creating an empty file lets say about
1MB in size?
If it is 1 MB in size then it is not empty ;-) An empty file would be 0
bytes in size.
To create a file of a fixed length, create the file, then seek its position
to the desired offset and call SetEndOfFile(). Note that the contents of
the space will be unintialized and random. You could optionally fill in the
space with zeros afterwards.
Quote
I am trying to learn how to use two threads to write to a file,
but my{*word*128}step is creating the empty file first, then writing to
the file afterwards.
One way is as follows:
class TMyThread : public TThread
{
private:
AnsiString FileName;
int StartOffset;
int NumBytes;
protected:
virtual void __fastcall Execute();
public:
__fastcall TMyThread(const AnsiString &AFileName, int AStartOffset,
int ANumBytes);
};
__fastcall TMyThread::TMyThread(const AnsiString &AFileName, int
AStartOffset, int ANumBytes)
: TThread(true)
{
FreeOnTerminate = true;
FileName = AFileName;
StartOffset = AStartOffset;
NumBytes = ANumBytes;
Resume();
}
void __fastcall TMyThread::Execute()
{
int iFile = FileOpen(FileName", fmOPenReadWrite);
if( iFile != -1 )
{
FileSeek(iFile, StartOffset);
// write up to NumBytes of data to the file...
FileClose(iFile);
}
}
{
if( !FileExists("filename") )
{
int iFile = FileCreate("filename");
FileSeek(iFile, 300);
::SetEndOfFile((HANDLE)iFile);
FileClose(iFile);
}
new TMyThread("filename", 0, 100);
new TMyThread("filename", 100, 100);
new TMyThread("filename", 200, 100);
//...
}
Gambit
 

Re:Create an empty file

"Ed Mulroy [TeamB]" < XXXX@XXXXX.COM >wrote in message
Quote
If I remember correctly, the limit on file size with this is 2Gig - 2
bytes.
SetFilePointer() accepts 64-bit offsets (which is unsigned when seeking from
offset 0), so the max file size is not 2GB.
Gambit
 

Re:Create an empty file

You have no idea how much I appreciate this, I was just going crazy trying
to figure out how to use SetFilePointer(). I was just about to post a
message
when I saw your response.
Thanks again
CJ
 

Re:Create an empty file

You are correct. I remembered it wrong.
-------------------------
lpDistanceToMoveHigh
Points to the high-order word of the 64-bit distance to move. If
the value of this parameter is NULL, SetFilePointer can operate
only on files whose maximum size is 2^32 - 2. If this parameter
is specified, the maximum file size is 2^64 - 2. This parameter
also receives the high-order word of the new value of the file
pointer.
-------------------------
Good catch!
. Ed
Quote
Remy Lebeau wrote in message
news: XXXX@XXXXX.COM ...

>If I remember correctly, the limit on file size with this is 2Gig - 2
>bytes.

SetFilePointer() accepts 64-bit offsets (which is unsigned when seeking
from offset 0), so the max file size is not 2GB.
 

Re:Create an empty file

This is where I am stuck,
HANDLE hFile = CreateFile("test.tst", GENERIC_READ, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
SetEndOfFile(hFile);
CloseHandle(hFile);
}
I am having a problem trying to figure out how to create the file of the
size that I want.
The SetFilePointer() is whats getting to me, I dont userstand the lo and hi
.
 

Re:Create an empty file

"Ed Mulroy [TeamB]" < XXXX@XXXXX.COM >wrote in message
Quote
lpDistanceToMoveHigh

Points to the high-order word of the 64-bit distance to move. If
the value of this parameter is NULL, SetFilePointer can operate
only on files whose maximum size is 2^32 - 2. If this parameter
is specified, the maximum file size is 2^64 - 2. This parameter
also receives the high-order word of the new value of the file
pointer.
Also:
"If FILE_BEGIN is specified, DistanceToMove is interpreted as an
unsigned location for the new file pointer."
Gambit
 

Re:Create an empty file

"CJ" < XXXX@XXXXX.COM >wrote in message
Quote
HANDLE hFile = CreateFile("test.tst", ...
You should always use absolute paths.
Quote
... CREATE_ALWAYS
If the file already exists, it will be wiped out.
Quote
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
You are seeking to offset 0, which is where a file always begins when it is
opened.
Quote
SetEndOfFile(hFile);
Since you seeked to offset 0, you are setting the file to be 0 bytes in
size, which it already is since you used the CREATE_ALWAYS flag.
Quote
I am having a problem trying to figure out how to create the
file of the size that I want. The SetFilePointer() is whats
getting to me, I dont userstand the lo and hi
ULARGE_INTEGER ul;
ul.QuadPart = whatever size you want;
ul.LowPart = SetFilePointer(hFile, (LONG)ul.LowPart,
(PLONG)&ul.HighPart, FILE_BEGIN);
if( (ul.LowPart == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
{
// an error occured...
}
else
{
// ul.QuadPart contains the new file position ...
}
Gambit
 

Re:Create an empty file

I tried this and my file is still zero bytes, I guess I am missing something
because I am not seeing any errors while debugging. I tried a number
like 2MB to see what would happen.
I am under the impression that when I create the 2MB file, it will be a file
thats 2MB in size, but it will contain only zeroes. Is that correct?
ULARGE_INTEGER ul;
ul.QuadPart = 2048;
HANDLE hFile = CreateFile("test.tst", GENERIC_READ, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
ul.LowPart = SetFilePointer(hFile, (LONG)ul.LowPart, (PLONG)&ul.HighPart,
FILE_BEGIN);
if((ul.LowPart == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
{
// an error occured...
}
else
{
// ul.QuadPart contains the new file position ...
}
SetEndOfFile(hFile);
CloseHandle(hFile);
}
 

Re:Create an empty file

"CJ" < XXXX@XXXXX.COM >wrote in message
Quote
I tried this and my file is still zero bytes
If you read the documentation for SetEndOfFile(), the file must be created
with GENERIC_WRITE access. Since your code is not doing that,
SetEndOfFile() is failing, but you are not checking its return value for
that.
Quote
I tried a number like 2MB to see what would happen.
You used 2KB, not 2MB.
Quote
I am under the impression that when I create the 2MB file,
it will be a file thats 2MB in size, but it will contain only
zeroes. Is that correct?
As I told you earlier, the contents of the new file space will be
unintialized with random values. If you want zeros, you have to fill them
in yourself after sizing the file.
Gambit
 

Re:Create an empty file

Hi,
I use TFileStream, so something like this seems to work (although the
contents of the file are undefined, but I find more often than not that it
is set to zero)
// create object
TFileStream * fHandle = new TFileStream( AnsiString(fName), (fmCreate |
fmShareDenyWrite) );
// set to beginning
fHandle->Seek( 0, soFromBeginning );
// set size
fHandle->Size = 1000000;
// goto end
fHandle->Seek( 0, soFromEnd );
// close file / delete object
delete fHandle
Regards,
Paul
"CJ" < XXXX@XXXXX.COM >wrote in message
Quote
How do you go about in creating an empty file lets say about
1MB in size?

I am trying to learn how to use two threads to write to a file,
but my{*word*128}step is creating the empty file first, then writing to
the file afterwards.

The programs that I have seen do this is download managers,
and torrent programs.

TIA

CJ


 

Re:Create an empty file

Hi, thanks for the feedback. I finally came up with something
that seems to work, and I noticed that the file is filled with
zeroes when its created.
This code I am just looking at the size of files, some files it displays
the correct file size, and the huge files it doesn't display the corect
size.
HANDLE hFile;
DWORD dwSize = 0;
DWORD dwSizeHigh = 0;
if(OpenDialog->Execute())
{
hFile = CreateFile(OpenDialog->FileName.c_str(), GENERIC_READ,
FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// Try to obtain hFile's size
dwSize = GetFileSize(hFile, &dwSizeHigh);
// If we failed ...
if(dwSize == INVALID_FILE_SIZE && (GetLastError()) != NO_ERROR)
{
// Dislay the error message
ShowMessage(SysErrorMessage(GetLastError()));
}
ShowMessage(dwSize);
if(!hFile) CloseHandle(hFile);
}
If I look at a file thats is about 5MB, it displays it correctly. Out of
curiosity I looked at a
4.1GB file, and it only reported the file as 172MB. Am I missing a function
call or something?
Thanks
CJ
 

Re:Create an empty file

Quote
...but it will contain only zeroes. Is that correct? ...
No.
Depending upon the version of Windows it may be filled with zeros or it may
be whatever was in that part of the disk. Later versions of Windows seem to
zero out the tracks and some utilities depend upon that but the
documentation that I have seen says that the added tracks contain data which
is undefined.
. Ed
Quote
CJ wrote in message
news:472bf69b$ XXXX@XXXXX.COM ...