Which low-level I/O API is better? MFC or POSIX
-
Few years ago we ported our application low-level to MFC. Instead of using open, read, write etc. we moved to MFC specifics like CreateFile(), ReadFile & WriteFile. We also did the same for the locking functions i.e. use LockFileEx instead of fcntl. Recently we start using WRITE_THROUGH flags everywhere to force direct writing to disk rather than via O.S system cache. Whilst most customers are happy and solved few of their problems some of them still have issues that are hard to track and reproduce. Hence there is a thought to go back to POSIX I/O API but this may creates us again more problems than it solves. My question is the following: Assuming that we are targeting a Win32 platform (XP and Vista) which I/O is the better low-level I/O it terms of a) performance, b) security of the following choices? i. MFC specific functions like CreateFile, LockFileEx etc. ii. POSIX style low-level I/O API like _open(), _fcntl()using a VC++ compiler iii. POSIX style low-level I/O but this time using a late version gcc/g++ compiler. If someone has the same dillemas would be nice to hear the views. Also if someone knows any article or comparisons could you please direct me to them? Thanks.
-
Few years ago we ported our application low-level to MFC. Instead of using open, read, write etc. we moved to MFC specifics like CreateFile(), ReadFile & WriteFile. We also did the same for the locking functions i.e. use LockFileEx instead of fcntl. Recently we start using WRITE_THROUGH flags everywhere to force direct writing to disk rather than via O.S system cache. Whilst most customers are happy and solved few of their problems some of them still have issues that are hard to track and reproduce. Hence there is a thought to go back to POSIX I/O API but this may creates us again more problems than it solves. My question is the following: Assuming that we are targeting a Win32 platform (XP and Vista) which I/O is the better low-level I/O it terms of a) performance, b) security of the following choices? i. MFC specific functions like CreateFile, LockFileEx etc. ii. POSIX style low-level I/O API like _open(), _fcntl()using a VC++ compiler iii. POSIX style low-level I/O but this time using a late version gcc/g++ compiler. If someone has the same dillemas would be nice to hear the views. Also if someone knows any article or comparisons could you please direct me to them? Thanks.
If you're targetting only Windows then I would (politely) suggest you
Win32 API
, such asCreateFile, LockFileEx,
etc.. :)If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
[My articles] -
Few years ago we ported our application low-level to MFC. Instead of using open, read, write etc. we moved to MFC specifics like CreateFile(), ReadFile & WriteFile. We also did the same for the locking functions i.e. use LockFileEx instead of fcntl. Recently we start using WRITE_THROUGH flags everywhere to force direct writing to disk rather than via O.S system cache. Whilst most customers are happy and solved few of their problems some of them still have issues that are hard to track and reproduce. Hence there is a thought to go back to POSIX I/O API but this may creates us again more problems than it solves. My question is the following: Assuming that we are targeting a Win32 platform (XP and Vista) which I/O is the better low-level I/O it terms of a) performance, b) security of the following choices? i. MFC specific functions like CreateFile, LockFileEx etc. ii. POSIX style low-level I/O API like _open(), _fcntl()using a VC++ compiler iii. POSIX style low-level I/O but this time using a late version gcc/g++ compiler. If someone has the same dillemas would be nice to hear the views. Also if someone knows any article or comparisons could you please direct me to them? Thanks.
Short answer If your only targeting Windows platforms use
CreateFile
. Longer answer The main reason you would want to use the CRT functions (open() close()
etc) is to make your program more portable there isn't any obvious advantage in speed or performance. That said, using win32 APIs does allows you to specify various parameters that CRT doesn't likeSecurity attributes
,Template file
etc. It doesn't really matter what compiler you use in terms of the APIs you call the CRT you will use is the same regardless of the compiler used. That said I don't see a reason to usegcc
to compile code for Windows. -
Short answer If your only targeting Windows platforms use
CreateFile
. Longer answer The main reason you would want to use the CRT functions (open() close()
etc) is to make your program more portable there isn't any obvious advantage in speed or performance. That said, using win32 APIs does allows you to specify various parameters that CRT doesn't likeSecurity attributes
,Template file
etc. It doesn't really matter what compiler you use in terms of the APIs you call the CRT you will use is the same regardless of the compiler used. That said I don't see a reason to usegcc
to compile code for Windows.I am aware of the portability benefits of CRT functions. I also know that in standard C their API derives from the UNIX system calls. To my knowledge in a UNIX system usually (if not always) there isn't a lower level I/O function than open, read etc. However, I couldn't find what happens in Win32 platforms. Are the CreateFile, ReadFile the equivalent of system calls? Does this mean that CRT functions like open or read are implemented using CreateFile and ReadFile. I suspect this is the case but I couldn't find any MS documentation stating that. It would be interesting actually to see outline of implementation of open/read etc using Win32 API and see what flags do they pass etc. if of course that's the way they have been written.
-
I am aware of the portability benefits of CRT functions. I also know that in standard C their API derives from the UNIX system calls. To my knowledge in a UNIX system usually (if not always) there isn't a lower level I/O function than open, read etc. However, I couldn't find what happens in Win32 platforms. Are the CreateFile, ReadFile the equivalent of system calls? Does this mean that CRT functions like open or read are implemented using CreateFile and ReadFile. I suspect this is the case but I couldn't find any MS documentation stating that. It would be interesting actually to see outline of implementation of open/read etc using Win32 API and see what flags do they pass etc. if of course that's the way they have been written.
Dimitris Vikeloudas wrote:
Does this mean that CRT functions like open or read are implemented using CreateFile and ReadFile.
Yes. On the Windows platform many of the CRT functions are nothing more than wrappers for their Windows API equivalents. The function in question... fopen will ultimately result in a call to the CreateFile Function[^] with the OPEN_EXISTING disposition. Which is yet another wrapper for CreateFileW if your in a non-unicode build. Calling CreateFileW with OPEN_EXISTING will result in a call to the NtOpenFile Function[^] which will push all the arguments on the stack and will pass through a call gate[^] via the SYSENTER instruction and result in a call to the ZwOpenFile[^] function. Best Wishes, -David Delaune
-
Dimitris Vikeloudas wrote:
Does this mean that CRT functions like open or read are implemented using CreateFile and ReadFile.
Yes. On the Windows platform many of the CRT functions are nothing more than wrappers for their Windows API equivalents. The function in question... fopen will ultimately result in a call to the CreateFile Function[^] with the OPEN_EXISTING disposition. Which is yet another wrapper for CreateFileW if your in a non-unicode build. Calling CreateFileW with OPEN_EXISTING will result in a call to the NtOpenFile Function[^] which will push all the arguments on the stack and will pass through a call gate[^] via the SYSENTER instruction and result in a call to the ZwOpenFile[^] function. Best Wishes, -David Delaune
Thanks a lot...That clarifies a lot the picture. I can suspect that compilers like g++ may provide their own implementation of open & read using the NtOpenFile or ZwOpenFile but from my perspective these internal functions are a no-go area. CreateFile etc are low-level enough :)