none
fflush() command does not work on Windows 7 local drives

    Question

  • Sign In to Vote

    The C++ fflush() command does not work on Windows 7 with sequential files created, written to local drives on Windows 7 PC's patched with all latest patches.

    When creating, writing files, the last part of the file does not always flush on closing, even when an additional fflush() command is added.

    This only applies to local drives, including memory sticks, floppy disc drives.

    However, if the output goes to any other non-Windows 7 PC or server on the network, it writes, flushes perfectly.

    The temporary solution is to write files to a network drive, then copy them back to the correct location.

    From checking the net, it appears that others have experienced the same problem, but can only advise disabling caching for the PC - this may impact on PC performance.

     

    Thursday, August 12, 2010 11:08 PM

Answers

  • Are you linking to commode.obj to enable commit-to-disk?

    See this similar thread:

    "fflush() has no effect on file streams
    opened with _fsopen() on Windows 7"

    http://social.msdn.microsoft.com/forums/en-us/vcgeneral/thread/0BE93860-9D3F-4133-B981-0B507BB61D73

    Also see:

    fflush
    http://msdn.microsoft.com/en-us/library/9yky46tz(VS.90).aspx

    Excerpt:

    "Buffers are normally maintained by the operating system,
    which determines the optimal time to write the data
    automatically to disk: when a buffer is full, when a stream
    is closed, or when a program terminates normally without
    closing the stream. The commit-to-disk feature of the
    run-time library lets you ensure that critical data is
    written directly to disk rather than to the operating-system
    buffers. Without rewriting an existing program, you can enable
    this feature by linking the program's object files with
    COMMODE.OBJ. In the resulting executable file, calls to
    _flushall write the contents of all buffers to disk.
    Only _flushall and fflush are affected by COMMODE.OBJ.

    For information about controlling the commit-to-disk feature,
    see Stream I/O, fopen, and _fdopen."

    - Wayne
    Friday, August 13, 2010 3:41 AM
  • std::fstream f("datafile.txt", std::ios::out);
    


    This approach from the STL works fine, so use it. It works fine for random files too by changing to

     

    std::fstream f("datafile.txt", std::ios::binary);


    Vote if answered or helpful, I am running for Office (joke)! IT/Developer, Windows/Linux/Mainframe I also am a true vegan and I am very good with economics and I used to play chess at 2400++ I have lots of papers on my site for power supplies and video card problems, see the resources section
    Friday, August 13, 2010 3:45 AM
  • The code is very simple and has been working for many years. The important point is that at the level of fopen, fclose, fflush the outcome should not differ if written to the C drive instead of a network drive. The problem only occurs on Windows 7 PCs, and has been reproduced at several of our sites.

    The problem seems to hit small files more than larger files, but this may not be relevant.

    COMMODE.OBJ is linked in as standard.

    Here are the create, close procedures. The seek back to zero line was added to see if this forced a flush when fflush() didn't.

    FHANDLE G3createfile(BYTEP filename)
    {
     FILE *fp;

     RESULT2 = 0;
     FileErrSimple = _T("");
     FileErrDetail = _T("");

     if (filename == NULL)
         {
           return NULL;
        }
     

    if (strlen((const char *)filename) < 2)
     {
       return NULL;
     }

     if( ( fp = fopen( (const char *)filename, "w+bc" ) ) == NULL )
         {
            RESULT2 = 2;

             fperror( filename, RESULT2 );

             return ( NULL );
        }
     else
       {
             return( fp );
        }
    }

    void G3closefile(FHANDLE fp)
    {
    if (fp == NULL)
     {
      return;
     }

    fflush( fp );

    // Go back to origin
    fseek( fp, (long) 0, FS_SET );

    fflush( fp );
    fclose( fp );

    }
     

     

     

    Saturday, August 14, 2010 3:25 PM

All replies

  • I'm unable to reproduce. Do you have a compilable sample which demonstrates the problem?
    Friday, August 13, 2010 3:35 AM
  • Are you linking to commode.obj to enable commit-to-disk?

    See this similar thread:

    "fflush() has no effect on file streams
    opened with _fsopen() on Windows 7"

    http://social.msdn.microsoft.com/forums/en-us/vcgeneral/thread/0BE93860-9D3F-4133-B981-0B507BB61D73

    Also see:

    fflush
    http://msdn.microsoft.com/en-us/library/9yky46tz(VS.90).aspx

    Excerpt:

    "Buffers are normally maintained by the operating system,
    which determines the optimal time to write the data
    automatically to disk: when a buffer is full, when a stream
    is closed, or when a program terminates normally without
    closing the stream. The commit-to-disk feature of the
    run-time library lets you ensure that critical data is
    written directly to disk rather than to the operating-system
    buffers. Without rewriting an existing program, you can enable
    this feature by linking the program's object files with
    COMMODE.OBJ. In the resulting executable file, calls to
    _flushall write the contents of all buffers to disk.
    Only _flushall and fflush are affected by COMMODE.OBJ.

    For information about controlling the commit-to-disk feature,
    see Stream I/O, fopen, and _fdopen."

    - Wayne
    Friday, August 13, 2010 3:41 AM
  • The code is very simple and has been working for many years. The important point is that at the level of fopen, fclose, fflush the outcome should not differ if written to the C drive instead of a network drive. The problem only occurs on Windows 7 PCs, and has been reproduced at several of our sites.

    The problem seems to hit small files more than larger files, but this may not be relevant.

    COMMODE.OBJ is linked in as standard.

    Here are the create, close procedures. The seek back to zero line was added to see if this forced a flush when fflush() didn't.

    FHANDLE G3createfile(BYTEP filename)
    {
     FILE *fp;

     RESULT2 = 0;
     FileErrSimple = _T("");
     FileErrDetail = _T("");

     if (filename == NULL)
         {
           return NULL;
        }
     

    if (strlen((const char *)filename) < 2)
     {
       return NULL;
     }

     if( ( fp = fopen( (const char *)filename, "w+bc" ) ) == NULL )
         {
            RESULT2 = 2;

             fperror( filename, RESULT2 );

             return ( NULL );
        }
     else
       {
             return( fp );
        }
    }

    void G3closefile(FHANDLE fp)
    {
    if (fp == NULL)
     {
      return;
     }

    fflush( fp );

    // Go back to origin
    fseek( fp, (long) 0, FS_SET );

    fflush( fp );
    fclose( fp );

    }
     

     

     

    Saturday, August 14, 2010 3:25 PM
  •  

    Hi johnggold,

     

    Did you solve the issue? And do you think Vegan's idea is helpful, if so please mark answer, if not please show your problem let me know.

     

    Regards!

    Jesse


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Tuesday, August 17, 2010 8:26 AM