Hi,
Are there any better ways to determine file length than iterating ReadFile until it hits EOF?
EDIT: D'oh!!!! GetFileSize. :boohoo:
Best regards,
Robin.
GetFileSizeEx ?
http://msdn.microsoft.com/en-us/library/aa364957%28VS.85%29.aspx
:P
:thumbu
Best regards,
Robin.
Whoa... I get weird behavior:
assume edx:ptr _LARGE_INTEGER
lea edx,LargeInteger
print str$([edx].LowPart)
assume edx:nothing
prints '4' as expected.
assume edx:ptr _LARGE_INTEGER
lea edx,LargeInteger
print str$([edx].HighPart)
assume edx:nothing
prints '0' as expected.
But.......
assume edx:ptr _LARGE_INTEGER
lea edx,LargeInteger
print str$([edx].HighPart)
print str$([edx].LowPart)
assume edx:nothing
prints the strange number '0614763971'. :eek
Best regards,
Robin.
the first "print" probably destroys the contents of EDX
push edx
print.....
pop edx
print....
Quote from: Astro on February 20, 2010, 05:27:52 PM
EDIT: D'oh!!!! GetFileSize. :boohoo:
FindFirstFile: WIN32_FIND_DATA.nFileSizeLow
Over a network share, CreateFile then GetFileSize is dozens of times slower than just using FindFirstFile to get at the size
http://msdn.microsoft.com/en-us/library/aa364955%28VS.85%29.aspx
Interesting. I think GetFileAttributesEx is also a great choice, according to the same person, what do you think ?
Better to use 1 API call than 2, that's for sure.
or FindFirstFileA / FindFirstFileW - which gives more information than the other api's such as file create time, size, last write time etc.. :)
Quote from: evlncrn8 on February 21, 2010, 01:00:32 PM
or FindFirstFileA / FindFirstFileW - which gives more information than the other api's such as file create time, size, last write time etc.. :)
Those return the same info as GetFileAttributesEx. And I guess there's more overhead to them.
I agree, GetFileAttributesEx is the best way to go and is the only way I do it. After all, it was designed to do just that. The other APIs add the feature but it is not central to the purpose of those APIs.
Paul
Quote from: PBrennick on February 21, 2010, 01:22:32 PM
I agree, GetFileAttributesEx is the best way to go and is the only way I do it. After all, it was designed to do just that. The other APIs add the feature but it is not central to the purpose of those APIs.
Paul
It seems Paul is right:
217157 cycles for 3*FindFirstFile
57595 cycles for 3*GetFileAttributesEx
679499 cycles for 3*GetFileSize
EDIT: The GetFileAttributesEx is relatively short...
GetFileLen2 proc fname
LOCAL wfad:WIN32_FILE_ATTRIBUTE_DATA
call ClearLocVars
push ebx
lea ebx, wfad
GetFileExInfoStandard = 0
invoke GetFileAttributesEx, fname, GetFileExInfoStandard, ebx
dec eax ; GfaEx returns zero for an error, but that collides with zero being a valid length
.if !Sign?
mov eax, [ebx.WIN32_FILE_ATTRIBUTE_DATA.nFileSizeLow]
mov edx, [ebx.WIN32_FILE_ATTRIBUTE_DATA.nFileSizeHigh]
.endif
pop ebx
ret
GetFileLen2 endp
... but has two drawbacks:
First, you must invent your own error handling. The API call returns zero if an error occurs, but a file with zero length is pretty common. I chose above a
dec eax, short and clear: eax==-1 means an error. Except for the case of a 4294967295 bytes file...
You can even eliminate that last bit of ambiguity by testing for the sign flag:
invoke GetFileLen2, offset FileA
.if Sign?
MsgBox 0, "An error", "Hi", MB_OK
.endif
Second, GetFileExInfoStandard is zero but there is no guarantee that it stays that way (I bet it will but...):
fInfoLevelId (http://msdn.microsoft.com/en-us/library/aa364946%28VS.85%29.aspx)[in]
A class of attribute information to retrieve.
This parameter can be the following value from the GET_FILEEX_INFO_LEVELS enumeration.
Value Meaning
GetFileExInfoStandard
The lpFileInformation parameter is a WIN32_FILE_ATTRIBUTE_DATA structure.
Common sense indicates "put a zero", but MS has deliberately chosen to deliver hilariously obscure documentation.
but - uh oh - my file sizes don't match yours, Jochen
148082 is incorrect (GetFileLen1 A)
that is for masm32.lib :eek
my lib file is 148082 bytes
Quote from: dedndave on February 22, 2010, 12:34:59 AM
but - uh oh - my file sizes don't match yours, Jochen
That's why I put the equates, Dave :green
I made a little goasm example proggy, just run it, select the file you want and it will show the bytesize (only works up to 4gb files)
#dynamiclinkfile kernel32.dll user32.dll comdlg32.dll
#include windows.h
DATA SECTION
sz_ProgramTitle db "Sizer",0
sz_1 db "File size is %lu bytes !",0
sz_Titlestring db "Select file to get filesize",0
sz_Error db "Error",0
sz_apifailed db "Couldn't get info from file",0
h_console_out dd 0
namebuffer db 128 dup 0
buffer db 128 dup 0
ofn OPENFILENAME <>
fad WIN32_FILE_ATTRIBUTE_DATA <>
CODE SECTION
START:
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov [h_console_out], eax
mov D[ofn.lStructSize],SIZEOF ofn
mov D[ofn.lpstrFile], OFFSET namebuffer
mov D[ofn.nMaxFile], SIZEOF namebuffer
mov D[ofn.lpstrTitle] , addr sz_Titlestring
mov D[ofn.Flags], OFN_FILEMUSTEXIST + OFN_PATHMUSTEXIST + OFN_EXPLORER + OFN_HIDEREADONLY + OFN_NOCHANGEDIR
invoke GetOpenFileName , addr ofn
test eax,eax
jnz > @@
invoke ExitProcess, 0DEADh
@@:
invoke GetFileAttributesEx, addr namebuffer, GetFileExInfoStandard, addr fad
test eax,eax
jnz > @1
invoke MessageBox, NULL, addr sz_apifailed, addr sz_Error, MB_OK + MB_ICONWARNING
invoke ExitProcess, 0ACDCh
@1:
mov eax, [fad.nFileSizeLow]
invoke wsprintf , addr buffer, addr sz_1, eax
invoke MessageBox, NULL, addr buffer, addr sz_ProgramTitle, MB_OK
invoke ExitProcess, NULL
No commenting needed, first paragraph gets the full pathname, second gets the size and then I show it in a MsgBox. I'll attach a compiled binary for testing.
EDIT: Just noticed that uneeded extra command mov eax, ... that was for easier debugging, nvm.
i see the equates :bg
but - i am wondering why the masm32.lib file sizes are different
Quote from: dedndave on February 22, 2010, 11:15:40 AM
i see the equates :bg
but - i am wondering why the masm32.lib file sizes are different
My other puter says masm32.lib = 148082 of 22.4.09
Maybe one day Hutch will add a readme.txt containing the word "version" ;-)
oh - ok - we are the same
the value you have in the equate is 148076