【问题标题】:Creating and deleting files from C/C++从 C/C++ 创建和删除文件
【发布时间】:2014-07-17 14:55:42
【问题描述】:

我似乎对文件删除在 Linux 上的工作方式感到困惑(在 Mac OS X 上的行为相同)。以下代码写入一个 1GB 的文件,然后立即将其删除。它这样做了 1024 次。我认为由于文件已关闭,它将立即被删除(回收空间,甚至可能回收文件描述符)。相反,如果我查看lsof,该文件仍被声称为进程所有(附加了(删除))。如果我看df,空间还是用完了。最终,进程因耗尽允许的打开文件数、我可以提高的限制或空间不足而终止。

这样做的正确方法是什么?我是否可以在进程终止之前删除文件(并回收其空间),或者这是一个没有希望的练习,我需要为我的代码设计另一种设计?

#include <unistd.h>
#include <cstdlib>
#include <cstdio>
#include <fcntl.h>

#include <iostream>

int main()
{
    size_t n = 1024*1024*1024;
    void* buffer = malloc(n);
    std::cout << "Buffer created" << std::endl;

    for (unsigned i = 0; i < 1024; ++i)
    {
        char filename[50] = "STORAGE.XXXXXX";
        mkstemp(filename);
        std::cout << filename << std::endl;
        int fh = open(filename, O_WRONLY | O_SYNC, 0600);
        write(fh, buffer, n);
        close(fh);
        remove(filename);
    }
    free(buffer);
    sleep(60);
}

lsof:

test-remo 29251 ...    3u   REG   8,51 1073741824  9307914 .../tmp/STORAGE.Tyj4oG (deleted)
test-remo 29251 ...    4u   REG   8,51 1073741824  9308254 .../tmp/STORAGE.fBkF5b (deleted)
test-remo 29251 ...    5u   REG   8,51 1073741824  9308030 .../tmp/STORAGE.xfJ9P0 (deleted)
test-remo 29251 ...    6u   REG   8,51 1073741824  9308538 .../tmp/STORAGE.0C6oea (deleted)
test-remo 29251 ...    7u   REG   8,51 1073741824  9306147 .../tmp/STORAGE.w9dPzC (deleted)
test-remo 29251 ...    8u   REG   8,51 1073741824  9308311 .../tmp/STORAGE.mIwcpq (deleted)
test-remo 29251 ...    9u   REG   8,51 1073741824  9309004 .../tmp/STORAGE.srTZfy (deleted)
test-remo 29251 ...   10u   REG   8,51 1073741824  9309284 .../tmp/STORAGE.xjQQ4Y (deleted)
test-remo 29251 ...   11u   REG   8,51 1073741824  9309291 .../tmp/STORAGE.ioyPxI (deleted)
test-remo 29251 ...   12u   REG   8,51 1073741824  9307415 .../tmp/STORAGE.saYo2L (deleted)
test-remo 29251 ...   13u   REG   8,51 1073741824  9307810 .../tmp/STORAGE.ylW467 (deleted)
test-remo 29251 ...   14u   REG   8,51 1073741824  9308666 .../tmp/STORAGE.lUYnWN (deleted)
test-remo 29251 ...   15u   REG   8,51 1073741824  9309678 .../tmp/STORAGE.1rZM4M (deleted)
test-remo 29251 ...   16u   REG   8,51 1073741824  9309702 .../tmp/STORAGE.wdggra (deleted)
test-remo 29251 ...   17u   REG   8,51 1073741824  9309687 .../tmp/STORAGE.qczYAS (deleted)
test-remo 29251 ...   18u   REG   8,51 1073741824  9309732 .../tmp/STORAGE.u0IxKV (deleted)
test-remo 29251 ...   19u   REG   8,51 1073741824  9309708 .../tmp/STORAGE.6SiMpi (deleted)
test-remo 29251 ...   20u   REG   8,51 1073741824  9308649 .../tmp/STORAGE.URky5Z (deleted)
test-remo 29251 ...   21u   REG   8,51 1073741824  9309740 .../tmp/STORAGE.j8wEq2 (deleted)
test-remo 29251 ...   22u   REG   8,51 1073741824  9309677 .../tmp/STORAGE.Wj5rco (deleted)
test-remo 29251 ...   23u   REG   8,51 1073741824  9309828 .../tmp/STORAGE.I38ln3 (deleted)
test-remo 29251 ...   24u   REG   8,51 1073741824  9309839 .../tmp/STORAGE.ent8I1 (deleted)
test-remo 29251 ...   25u   REG   8,51 1073741824  9309843 .../tmp/STORAGE.1361nk (deleted)
test-remo 29251 ...   26u   REG   8,51 1073741824  9309824 .../tmp/STORAGE.ue2WkW (deleted)
test-remo 29251 ...   27u   REG   8,51 1073741824  9312037 .../tmp/STORAGE.4MdKsR (deleted)
test-remo 29251 ...   28u   REG   8,51 1073741824  9312042 .../tmp/STORAGE.EgDft5 (deleted)
test-remo 29251 ...   29u   REG   8,51 1073741824  9312059 .../tmp/STORAGE.NRcqlE (deleted)
test-remo 29251 ...   30u   REG   8,51 1073741824  9309847 .../tmp/STORAGE.cF9qYw (deleted)
test-remo 29251 ...   31u   REG   8,51 1073741824  9312103 .../tmp/STORAGE.wzfhSI (deleted)
test-remo 29251 ...   32u   REG   8,51 1073741824  9312120 .../tmp/STORAGE.hfdv1d (deleted)
test-remo 29251 ...   33u   REG   8,51 1073741824  9312090 .../tmp/STORAGE.kSX2D4 (deleted)
test-remo 29251 ...   34u   REG   8,51 1073741824  9309813 .../tmp/STORAGE.FWKVGf (deleted)
test-remo 29251 ...   35u   REG   8,51 1073741824  9312148 .../tmp/STORAGE.CYPGGL (deleted)
test-remo 29251 ...   36u   REG   8,51 1073741824  9312171 .../tmp/STORAGE.it4bmC (deleted)
test-remo 29251 ...   37u   REG   8,51 1073741824  9312145 .../tmp/STORAGE.IGSzVO (deleted)
test-remo 29251 ...   38u   REG   8,51 1073741824  9312228 .../tmp/STORAGE.CMSOil

【问题讨论】:

    标签: c++ c file filesystems lsof


    【解决方案1】:

    当您调用mkstemp 时,它不仅会创建一个临时文件,还会打开它并返回一个文件句柄。

    #include <unistd.h>
    #include <cstdlib>
    #include <cstdio>
    #include <fcntl.h>
    
    #include <iostream>
    
    int main()
    {
        size_t n = 1024*1024*1024;
        void* buffer = malloc(n);
        std::cout << "Buffer created" << std::endl;
    
        for (unsigned i = 0; i < 1024; ++i)
        {
            char filename[50] = "STORAGE.XXXXXX";
    
            int fh;
            fh = mkstemp(filename);
            // close(fh)
            std::cout << filename << std::endl;
            // fh = open(filename, O_WRONLY | O_SYNC, 0600);
            write(fh, buffer, n);
            close(fh);
            remove(filename);
        }
        free(buffer);
        sleep(60);
    }
    

    如果你想用 WRONLY 和 SYNC 打开它,那么你必须先关闭返回的文件句柄,然后重新打开它,如果你愿意的话。在这种情况下,只需删除closeopen 之前的// 注释标记,或者改用mkostemp

    NAME
           mkstemp, mkostemp, mkstemps, mkostemps - create a unique temporary file
    
    SYNOPSIS
           #include <stdlib.h>
    
           int mkstemp(char *template);
           int mkostemp(char *template, int flags);
    
    
    RETURN VALUE
         On success, these functions return the file descriptor of the  temporary  file.
         On error, -1 is returned, and errno is set appropriately.
    

    【讨论】:

    • 是的,POSIX 系统不会回收已删除文件使用的空间,直到该文件的所有句柄都关闭。
    • 哦,太棒了!我误解了 mkstemp。现在一切都变得有意义并检查了。感谢您的帮助!
    • mkstemp 旨在安全地创建临时文件。如果您关闭并重新打开它,那么另一个进程可能会与您竞争并打开创建的文件。正如您所指出的,最好使用mkostemp
    猜你喜欢
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 2012-02-11
    • 1970-01-01
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    相关资源
    最近更新 更多