Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use CreateFile, but force the handle into a std::ofstream?

Is there any way to take advantage of the file creation flags in the Win32 API such as FILE_FLAG_DELETE_ON_CLOSE or FILE_FLAG_WRITE_THROUGH as described here http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx , but then force that handle into a std::ofstream?

The interface to ofstream is obviously platform independent; I'd like to force some platform dependent settings in 'under the hood' as it were.

like image 426
Steve Folly Avatar asked Jan 24 '09 10:01

Steve Folly


People also ask

What happens if you try to open a file for writing that doesn't exist C++?

If the file doesn't exist, a new file is created. Returns NULL, if unable to open the file. The file is opened for reading and appending(writing at end of file).

Does ofstream need to be closed?

So no, we do not need to explicitly call fstream::close() to close the file. After open a file with fstream/ifstream/ofstream, it is safe to throw an exception without manually close the file first.

Is ofstream a header file?

Explanation: In the above program, the header file fstream is imported to enable us to use ofstream and ifstream in the program. Then another header file iostream is imported to enable us to use cout and cin in the program. Then the standard namespace std is used.


1 Answers

It is possible to attach a C++ std::ofstream to a Windows file handle. The following code works in VS2008:

HANDLE file_handle = CreateFile(
    file_name, GENERIC_WRITE,
    0, NULL, CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL, NULL);

if (file_handle != INVALID_HANDLE_VALUE) {
    int file_descriptor = _open_osfhandle((intptr_t)file_handle, 0);

    if (file_descriptor != -1) {
        FILE* file = _fdopen(file_descriptor, "w");

        if (file != NULL) {
            std::ofstream stream(file);

            stream << "Hello World\n";

            // Closes stream, file, file_descriptor, and file_handle.
            stream.close();

            file = NULL;
            file_descriptor = -1;
            file_handle = INVALID_HANDLE_VALUE;
        }
}

This works with FILE_FLAG_DELETE_ON_CLOSE, but FILE_FLAG_WRITE_THROUGH may not have the desired effect, as data will be buffered by the std::ofstream object, and not be written directly to disk. Any data in the buffer will be flushed to the OS when stream.close() is called, however.

like image 126
ChrisN Avatar answered Sep 17 '22 18:09

ChrisN