Eveler
Eveler

Reputation: 173

CreateFile vs fopen vs ofsteam advantage & disadvantage?

CreateFile vs fopen vs ofsteam - advantage & disadvantage?

I heard that CreateFile powerful but only for windows.
Can you tell what should I use ( on windows) and why?

Upvotes: 12

Views: 10665

Answers (7)

Sirmabus
Sirmabus

Reputation: 726

The obvious and clear winner is "CreateFile". Why?, because it has the most options. With it you have control over the buffering, can give it some hints for sequential or random access (needs profiling to see if there is any actual performance advantage), plus control over security and sharing.

It fits best within the context of the OP's question of "power".

If you need the extra control and options use "CreateFile", but probably most of the time you are fine with the ubiquitous tried and true "fopen". Or if you are big on C++ OOP mechanics, use "ofsteam".

Upvotes: 1

user4590120
user4590120

Reputation:

I copied my answer from

fopen or CreateFile in Windows

which was closed for some reason which escapes me...

  1. There is no defined way for fopen() to return the system error code. There might be an undefined way to access errno, but this might or might not be identical with the system error code.
  2. Also, I don't think that there is an defined way to access the real system handle (of type HANDLE) which in turn you might want to use to pass on to one of the many win64 system calls which expect such a system handle (e.g. memory mapped IO)
  3. Using open() an integer represents the file handle, which is not the system handle (on windows).
  4. fopen() does not throw an exception in case of error. In order to have some RAII you would need to wrap it into a class.
  5. Wrapping CreateFile() into a class, is not more expensive than wrapping fopen() or open() into a class.
  6. Using the C++ feature (std::ofstream, std::ifstream) to write/read to/from files suffers from the same problem as fopen():
    • It does not throw by default on error. In order to enable this feature you need to call some method instead of being able to use some constructor argument -- means for RAII you would need to derive this class (in order to use it as a member/base class which throws on error).
    • It is undefined if one is able to retrieve the system error code from the exception thrown or if the message returned from what() tells you anything about the system error.
    • Using this stream interface there is no real pluggable interface to define the source or destination of reading from or writing to. Overloading the stream interface is quite cumbersome and error prone.
  7. Using C like programming (paying attention to or ignoring return codes and manually writing cleanup code) is the source of much evil (remember heart-bleed?)...

Conclusions:

  1. write a resource wrapper for CreateFile()/CloseHandle(). Resource wrapper is a class, which performs the do-action in the constructor and the undo-action in the destructor and throws an exception in case of error. There are many such pairs of system calls in every OS but especially in Win64.
  2. Write a system error exception class (to be used for the above class in case of CreateFile() fails and for all the other system errors) or investigate, what the new system_exception class (in C++0x) is actually doing and if it is sufficient.
  3. write a functional wrapper for ReadFile() and WriteFile() which converts a system error into a system exception object thrown...
  4. Potentially define your own interface to write to somewhere and read from somewhere so that you can implement other things independent from the type of source/destination to read from/write to.
  5. Writing a cache class which allows you to cache reading from somewhere or writing to somewhere is also child play. Of course the cache class should not know nor care about the source/destination you're writing to/reading from.

Don't be scared about these small tasks. You will actually know, what is happening in your code and these little pieces of code should be negligible (in amount of lines of code) compared to the code calling it. Also if you're using RAII for everything, the code calling into these utility classes, will be considerable less compared to when not using RAII and having to use two- or even more-step initialization and considerable less error prone. Replacing these utility classes with equivalent utility classes for other OS is also child play (using open()/close()/read()/write() on UNIXs).

And for the sake of the previous millennia don't read the google programming guidelines!

Upvotes: 1

user1149224
user1149224

Reputation:

If you want to use Windows file memory mapping you should use CreateFile (e.g. the HANDLE passed to CreateFileMapping API is the return value of CreateFile). Moreover, CreateFile offers higher customization options than C and C++ standard file API.

However, if you want to write portable code, or if you don't need Windows-specific features, C and C++ standard file APIs are just fine. In some tests, when processing large data, I noted some performance overhead of C++ I/O streams vs. raw C file API; if you happen to be in cases like this, you could simply wrap raw C file API in some C++ RAII class, and still use it in C++ code.

Upvotes: 3

cyco130
cyco130

Reputation: 4934

Unless you absoulutely need the extra functionality provided by OS API functions (like CreateFile) I'd reccommend using the standard library functions (like fopen or ofstream). This way your program will be more portable.

The only real advantage of using CreateFile that I can think of is overlapped I/O and maybe finer grained access rights.

Upvotes: 2

James Kanze
James Kanze

Reputation: 153909

It depends on what you're doing. For sequentially reading and writing text files, iostream is definitely the way to go. For anything involving transactional security or non-standard devices, you'll have to access the system directly (CreateFile or open). Even then, for sequential reading and writing of text, the best solution is to define your own streambuf, and use that with iostream.

I can't think of any context where fopen would be preferable.

Upvotes: 9

Some programmer dude
Some programmer dude

Reputation: 409166

Unless you need the features provided by the Windows file functions (e.g. overlapped I/O) then my suggestion is going with either iostreams in C++ or FILE (fopen and friends) in C.

Besides being more portable, you can also use formated input/output for text files, and for C++ it's easy to overload the output/input operators for your classes.

Upvotes: 4

Eelke
Eelke

Reputation: 21993

In most cases you will be better of using fopen in C or ofstream in C++. CreateFile gives some extra control over sharing and caching but does not provide formatting functionality.

Upvotes: 1

Related Questions