Best method to preallocate a big file?
Posted: Fri Nov 11, 2011 1:36 am
I'm looking for the best way to preallocate a big file before starting to write into it in order to make code simpler in the long run.
Let's assume this as basic app code:
Sadly the following Code is not officially supported for "security concerns" and therefore might break on any future PB update, so that can't be the best method...
On many *nix-filesystems and NTFS this method might produce a sparse file. A sparse file does not consume disk space for file-blocks that were skipped and never written. This also greatly benefits Virtual Machines with dynamically growing volumes.
Win-API as well as POSIX C API definition offer seeking commands with this functionality.
The C API definition requires the space that is freshly allocated to be zero. WinAPI states that the skipped block has undefined contents. And WinAPI only mentions security concerns for SetFileValidData that therefore requires special user privileges but not for SetEndOfFile.
http://pubs.opengroup.org/onlinepubs/00 ... fseek.html
http://msdn.microsoft.com/en-us/library ... s.85).aspx
http://msdn.microsoft.com/en-us/library ... s.85).aspx
But that's not what this Thread is about.
This seems to eat a lot of CPU power and breaks sparsity:
This seems to be a pretty stupid solution and breaks sparsity: (allocate memory just to have some bigger buffer to write?!)
There are other variants with a DataSection, a string or a struct of given size. Also I could preallocate that junk-buffer on application startup and keep it till end but that just sounds stupid as well.
Yes I know, we have plenty of resources on modern machines. And no, I don't like applications that are written with that thought in mind. The best example for such an app is the official ICQ client: Eats memory like there's no tomorrow and still is slow as hell.
Let's assume this as basic app code:
Code: Select all
Declare CreateFilePreallocated(fileId, filename.s, fileSize.q)
Define big_size.q
big_size = 1024 * 1024 ; 1mb for testing
; big_size = 1024 * 1024 * 1024 * 4 ; 4gb
CreateFilePreallocated(1, "blah.bin", big_size)
; write big_size of data nonsequentially (meaning that I might write the last byte just before the first)
CloseFile(1)
Code: Select all
Procedure CreateFilePreallocated(fileId, filename.s, fileSize.q)
CreateFile(fileId, filename)
FileSeek(fileId, fileSize)
TruncateFile(fileId)
FileSeek(fileId, 0)
EndProcedure
Win-API as well as POSIX C API definition offer seeking commands with this functionality.
The C API definition requires the space that is freshly allocated to be zero. WinAPI states that the skipped block has undefined contents. And WinAPI only mentions security concerns for SetFileValidData that therefore requires special user privileges but not for SetEndOfFile.
http://pubs.opengroup.org/onlinepubs/00 ... fseek.html
http://msdn.microsoft.com/en-us/library ... s.85).aspx
http://msdn.microsoft.com/en-us/library ... s.85).aspx
But that's not what this Thread is about.
This seems to eat a lot of CPU power and breaks sparsity:
Code: Select all
Procedure CreateFilePreallocated(fileId, filename.s, fileSize.q)
CreateFile(fileId, filename)
i.q
For i = 1 To fileSize-7 Step 8
WriteQuad(fileId, 0)
Next
i - 8
For i = i To fileSize
WriteByte(fileId, 0)
Next
FileSeek(fileId, 0)
EndProcedure
This seems to be a pretty stupid solution and breaks sparsity: (allocate memory just to have some bigger buffer to write?!)
Code: Select all
#FALLOC_STEP = 1024 * 1024 ; 1mb
Procedure CreateFilePreallocated(fileId, filename.s, fileSize.q)
CreateFile(fileId, filename)
*buf = AllocateMemory(#FALLOC_STEP)
While fileSize > 0
len.q
If fileSize > #FALLOC_STEP
len = #FALLOC_STEP
Else
len = fileSize
End
WriteData(fileId, *buf, len)
fileSize - len
Wend
FreeMemory(*buf)
FileSeek(fileId, 0)
EndProcedure
Yes I know, we have plenty of resources on modern machines. And no, I don't like applications that are written with that thought in mind. The best example for such an app is the official ICQ client: Eats memory like there's no tomorrow and still is slow as hell.