I have a C++ program that is writing to a file on Windows 7.  When I call f.flush() the NTFS file does not get bigger. Is there any way to force the file to get flushed?
            Asked
            
        
        
            Active
            
        
            Viewed 1,566 times
        
    1
            
            
         
    
    
        vy32
        
- 28,461
- 37
- 122
- 246
- 
                    Are you sure there is pending output? Also, fsync (or [`_commit`]()) is your friend (http://archives.postgresql.org/pgsql-hackers-win32/2003-11/msg00082.php) – sehe Nov 12 '11 at 21:30
- 
                    Oh, yes, I'm positive there is output. It's not pending --- it's been sent. But NTFS buffers. – vy32 Nov 12 '11 at 22:05
- 
                    It is a heavy CRT implementation detail. For the MSVC CRT it is done by passing 'c' (= commit) to the fopen() *mode* argument. Look through the source of the one you use. – Hans Passant Nov 12 '11 at 22:59
2 Answers
2
            You can look here:
How do I get the file HANDLE from the fopen FILE structure? 
the code looks like this:
 FlushFileBuffers((HANDLE) _fileno(_file));
do not forget call fflush(file), before call FlusFileBuffers.
For std::fstream and gnu stl, I checked it on my linux box, have no windows at home, but should work with mingw, may be need some modifications:
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <fstream>
#include <ext/stdio_filebuf.h>
int main(int argc, char *argv[])
{
    assert(argc == 2);
    std::ifstream f(argv[1]);
    assert(!!f);
/*
    //cin, cout etc
    __gnu_cxx::stdio_filebuf<char> *stdio_buf = dynamic_cast<__gnu_cxx::stdio_filebuf<char> *>(f.rdbuf());
    if (stdio_buf != 0) {
        printf("your fd is %d\n", stdio_buf->fd());
        return EXIT_SUCCESS;
    }
*/
    std::basic_filebuf<char> *file_buf = dynamic_cast<std::basic_filebuf<char> *>(f.rdbuf());
    if (file_buf != 0) {
        struct to_get_protected_member : public std::basic_filebuf<char> {
            int fd() { return _M_file.fd(); }
        };
        printf("your fd is %d\n", static_cast<to_get_protected_member *>(file_buf)->fd());
    }
    printf("what is going on?\n");
    return EXIT_FAILURE;
}
- 
                    
- 
                    This is more hard, in library that come with VS10, you can construct std::fstream object from FILE, on some other libraries, I saw std::fstream::fd method, to file descriptor from std::fstream. What compiler do you use? – fghj Nov 12 '11 at 21:13
- 
                    I'm using mingw as a cross-compiler from Fedora Core. So I'm using GNU STL. – vy32 Nov 12 '11 at 22:06
- 
                    
- 
                    Update my answer, to include code that I was used some time before to get file handle. – fghj Nov 12 '11 at 22:47
- 
                    @user1034749 This is much better than my `#define protected public` trick!! – nodakai Oct 05 '12 at 07:06
- 
                    
0
            
            
        flush only flushes the internal buffers kept by the standard library code.
To flush the OS's buffers, you'd need/want to call FlushFileBuffers (after calling f.flush()).
 
    
    
        Jerry Coffin
        
- 476,176
- 80
- 629
- 1,111
- 
                    That's great. However, `FlushFileBuffers` requires the hFile handle. How do I get that? http://msdn.microsoft.com/en-us/library/windows/desktop/aa364439(v=vs.85).aspx – vy32 Nov 12 '11 at 20:47
- 
                    fsync() doesn't do the trick; I need to call FlushFileBuffers; I just need to find the handle. – vy32 Nov 12 '11 at 21:36
 
    