什么时候使用flush()?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么时候使用flush()?相关的知识,希望对你有一定的参考价值。

参考技术A 当程序输出数据到文件或者套接字的时候,会用到flush方法。

这个方法有什么用?
You use flush() to clear the internal buffers(if any) and force write(i.e. flush) all the pending data in to the stream destination.

什么时候使用这个方法呢?
If another process (or thread) needs to examine the file while it's being written to, and it's important that the other process sees all the recent writes.
If the writing process might crash, and it's important that no writes to the file get lost.
If you're writing to the console, and need to make sure that every message is shown as soon as it's written.
以上,在程序正常退出或者异常退出之前,或者让其他进程及时看到,或者工程师想立即看到输出结果。

FileMapping写的内容什么时候会flush到磁盘?

FileMapping写的内容什么时候会flush到磁盘?

FileMapping写文件

这是个简单的file mapping 写文件例子:

void TestIOFileMapping() 
    HANDLE  hFile;

    hFile = CreateFile(L"testfilemapping.foo",
        GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (hFile == INVALID_HANDLE_VALUE)
    
        return;
    

    HANDLE hMapping = CreateFileMapping(hFile,
        NULL,
        PAGE_READWRITE,
        0,
        MAX_FILESIZE,
        NULL);

    if (hMapping == NULL)
    
        CloseHandle(hFile);
        return;
    

    char* puchData = (char*)MapViewOfFile(hMapping,
        FILE_MAP_WRITE,
        0,
        0,
        0);

    if (puchData == NULL)
    
        CloseHandle(hMapping);
        CloseHandle(hFile);
        return;
    

    for (int i = 0; i < 10; i++)
    
        memset(puchData + i * 1024, 0x41 + i, 1024);
    

    UnmapViewOfFile(puchData);

//    FlushFileBuffers(hFile);
    CloseHandle(hMapping);
    CloseHandle(hFile);

什么时候写入磁盘?

因为上面的例子里面没有调用FlushFileBuffers(hFile);
所以,内存什么时候写入磁盘还真不好说。
一般有这几种可能:

  1. IRP_MJ_WRITE的对应函数(比如PreWrite),直接就被调用,然后进程号就是当前应用。
  2. PreWrite很快被调用,但是发现进程号是System进程的,也就是4号
  3. PreWrite过了好长一会才被调用,进程号是System进程的,也就是4号
  4. PreWrite一直都没有被调用 (实际上可能在关机前会写入,只是不容易察觉)

那么有哪些操作会强迫操作系统把缓存里面的数据写入磁盘呢?

强迫操作系统写入磁盘

其实应该有很多种,我知道的,比如:

  1. 读取文件的时候加上no buffering标志。
hFile = CreateFile(L"testfilemapping.foo",
        GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_ALWAYS,
        FILE_FLAG_NO_BUFFERING,
        NULL);

当应用层这样去打开一个文件的时候,指定了FILE_FLAG_NO_BUFFERING,那么操作系统一看这个文件相关的还有部分内容在文件缓存里面,它就会先把内容写入磁盘,再返回CreateFile()。因为FILE_FLAG_NO_BUFFERING指的是从磁盘读取文件,操作系统需要保证数据一致性。
2. 通过CreateProcess之类的去创建一个进程(假如文件是个exe),那么操作系统也会在创建进程之前先把内容flush到磁盘
3. 。。。

以上是关于什么时候使用flush()?的主要内容,如果未能解决你的问题,请参考以下文章

FileMapping写的内容什么时候会flush到磁盘?

MySQL里flush tables是啥作用?

flush()的使用

文件操作的 flush 问题

java中flush具体的用法!!!

java的io流中,啥时候应该在流关闭之前加flush,啥时候不用