美文网首页
VC FILE*使用内存文件方法

VC FILE*使用内存文件方法

作者: 叶迎宪 | 来源:发表于2023-04-26 19:59 被阅读0次

    有一个第三方库,输入参数之一是文件名,会把输出的内容写到这个文件中。我的应用程序再从这个文件中读入内容。由于这个第三方库每次产生的输出都很大,有十几兆,连续调用会产生大量的磁盘io,拖累性能。有没有办法让这个输出文件只存在于内存中,避免产生磁盘io呢?

    尝试一:使用命名管道
    https://github.com/msys2/MINGW-packages/issues/5903

    示例

        HANDLE hpipe;
        char pipename[MAX_PATH];
    
        snprintf(pipename, sizeof(pipename), "\\\\.\\pipe\\msys_example_");
    
        hpipe = CreateNamedPipeA(pipename, PIPE_ACCESS_INBOUND,
            PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
            1, 1024, 1024, 0, NULL);
        if (hpipe == INVALID_HANDLE_VALUE)
        {
            fprintf(stderr, "Failed to create named pipe\n");
            return 1;
        }
    
    
        {  // 模拟第三方库打开并写入文件
            FILE* fp;
            fp = fopen(pipename, "wb");
            fprintf(fp, "abcd");
            fclose(fp);
        }
    
        {
            char buf[16];
            DWORD nBytesRead;
            ReadFile(hpipe, buf, 16, &nBytesRead, NULL);
        }
         
        CloseHandle(hpipe);
    
    

    不过要注意的是,往pipe调用fwrite写入数据,或者fclose的时候(之前fwrite的数据要flush)可能会卡住,如果接收端没有及时取走数据,导致pipe的buffer塞满。对于要写入大量数据的情况,需要对应用进行改造,pipe的写入和读取分开到两个线程上同时进行

    类似的linux下的方案
    https://www.ibm.com/docs/en/zos/2.3.0?topic=io-using-named-pipes

    尝试二:使用内存临时文件
    https://github.com/Snaipe/fmem/blob/b73b3d8b570c2f79df5a0b071efba392a82ddcd7/src/fmem-winapi-tmpfile.c

    其中的难点是 CreateFile 时的 (dwDesiredAccess, dwShareMode) 会影响影响后续打开是否成功
    https://learn.microsoft.com/en-us/windows/win32/fileio/creating-and-opening-files
    特别是如果带上了 FILE_FLAG_DELETE_ON_CLOSE,则要求 dwShareMode 带上 FILE_SHARE_DELETE,后续的打开也都要带上 FILE_SHARE_DELETE。而fopen等c库函数,都是不带FILE_SHARE_DELETE的。

    示例

        char path[MAX_PATH];
        char file[MAX_PATH];
    
        if (!GetTempPathA(sizeof(path), path))
            return NULL;
        if (!GetTempFileNameA(path, "test", 0, file))
            return NULL;
    
        HANDLE handle = INVALID_HANDLE_VALUE;
        handle = CreateFileA(file,
                FILE_GENERIC_READ,
                FILE_SHARE_WRITE | FILE_SHARE_READ,
                NULL,
                CREATE_ALWAYS,
                FILE_ATTRIBUTE_TEMPORARY,
                NULL);
    
        { // 模拟第三方库打开并写入文件
            FILE* fp;
            fp = fopen(file, "wb");
            fprintf(fp, "abcd");
            fclose(fp);
        }
    
        { 
            char buf[16];
            FILE* fp;
            fp = fopen(file, "rb");
            fread(buf, 1, 16, fp);
            fclose(fp);
        }
    
        CloseHandle(handle); DeleteFileA(file); 
    

    相关文章

      网友评论

          本文标题:VC FILE*使用内存文件方法

          本文链接:https://www.haomeiwen.com/subject/lwumjdtx.html