You truncate a file by calling SetFilePointer
or SetFilePointerEx
to the desired location followed by SetEndOfFile
. The following shows how a truncate
function can be implemented:
bool truncate( HANDLE hFile, LARGE_INTEGER NewSize ) {
LARGE_INTEGER Size = { 0 };
if ( GetFileSizeEx( hFile, &Size ) ) {
LARGE_INTEGER Distance = { 0 };
// Negative values move the pointer backward in the file
Distance.QuadPart = NewSize.QuadPart - Size.QuadPart;
return ( SetFilePointerEx( hFile, Distance, NULL, FILE_END ) &&
SetEndOfFile( hFile ) );
}
return false;
}
// Helper function taking a file name instead of a HANDLE
bool truncate( const std::wstring& PathName, LARGE_INTEGER NewSize ) {
HANDLE hFile = CreateFileW( PathName.c_str(), GENERIC_WRITE, FILE_SHARE_READ,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL );
if ( hFile == INVALID_HANDLE_VALUE ) {
return false;
}
bool Success = truncate( hFile, NewSize );
CloseHandle( hFile );
return Success;
}
EDIT: Shorter Version
The truncate
function can be shortened to the following:
bool truncate( HANDLE hFile, LARGE_INTEGER NewSize ) {
return ( SetFilePointerEx( hFile, NewSize, NULL, FILE_BEGIN ) &&
SetEndOfFile( hFile ) );
}
If you would rather want to pass the amount of bytes by which to shrink the file, the following implementation can be used:
bool truncate( HANDLE hFile, LARGE_INTEGER ShrinkBy ) {
ShrinkBy.QuadPart = -ShrinkBy.QuadPart;
return ( SetFilePointerEx( hFile, ShrinkBy, NULL, FILE_END ) &&
SetEndOfFile( hFile ) );
}
To grow a file, open the file using CreateFile
with a dwDesiredAccess
that contains FILE_APPEND_DATA
. Using SetFilePointer
again to set the file pointer to the end of file you can then write new data calling WriteFile
. For an example, see Appending One File to Another File.
EDIT: Growing a file without writing to it
If you don't care about the file contents beyond the original file size you can apply the same sequence as shown for truncating a file to extend it:
bool SetFileSize( HANDLE hFile, LARGE_INTEGER NewSize ) {
return ( SetFilePointerEx( hFile, NewSize, NULL, FILE_BEGIN ) &&
SetEndOfFile( hFile ) );
}
This is documented behavior for SetEndOfFile
:
The SetEndOfFile function can be used to truncate or extend a file. If the file is extended, the contents of the file between the old end of the file and the new end of the file are not defined.