如何在Linux上用C ++关闭文件?

时间:2010-07-05 19:01:37

标签: c++ linux filesystems

我希望只有在文件关闭时才能从磁盘中删除文件。在此之前,其他进程应该能够在磁盘上查看文件并读取其内容,但最终在文件关闭后,应该从磁盘中删除它,并且在磁盘上不再可见其他进程。

6 个答案:

答案 0 :(得分:10)

打开文件,然后在打开时将其删除。其他进程将能够使用该文件,但只要文件的所有句柄都关闭,它就会被删除。

编辑:基于WilliamKF后来添加的评论,这将无法实现他想要的东西 - 它将保持文件本身,直到它的所有句柄都关闭,目录条目只要您致电unlink / remove,文件名就会消失。

答案 1 :(得分:3)

答案 2 :(得分:2)

Unix中的打开文件是引用计数的。每open(2)递增计数器,每close(2)递减一次。计数器由系统上的所有进程共享。

然后是磁盘文件的链接计数。全新的文件得到一个。计数通过link(2)系统调用递增。 unlink(2)递减它。当此计数降至零时,文件将从文件系统中删除。

完成所要求的唯一方法是在一个过程中打开文件,然后unlink(2)。其他流程可以在open(2)stat(2) 之间open(2)unlink(2) 。假设该文件只有一个链接,当所有进程打开它时,它将被删除。

答案 3 :(得分:0)

不确定,但您可以尝试remove,但它看起来更像是c风格。

也许boost::filesystem::remove

bool remove( const path & ph );
  

前提条件:!ph.empty()

     

返回:exists(ph)的值   在成立之前   后置条件。

     

后置条件:!存在(ph)

     

抛出:如果ph.empty()|| (存在(PH)   &安培;&安培; is_directory(ph)&& !is_empty(PH))。   请参阅空路径原理。

     

注意:符号链接本身就是   删除,而不是他们指出的   被删除。

     

理由:不扔的时候   !存在(ph)因为不投掷:

     

如果ph是悬挂的话,可以正常工作   象征性的联系。稍微   更易于使用,适用于许多常见用途   案例。略高一点   因为它意味着使用   后置条件语义而不是   效果语义,这将是   在较低级别指定   与...的互动条款   操作系统。但是,有一个   一些人的安全性略有下降   错误会因此而失误   本来可以被发现的。例如,   错误的路径名称可以去   很长一段时间未被发现。

     

库的初始版本   当路径发生时抛出异常   不存在;它改变了以反映   用户投诉。

您可以使用上述方法之一删除de file来创建一个计算引用的包装类。

class MyFileClass{

    static unsigned _count;
 public:
    MyFileClass(std::string& path){
     //open file with path
     _count++;
    }

    //other methods

    ~MyFileClass(){

        if (! (--_count)){

          //delete file
        }

     }

    };

   unsigned MyFileClass::_count = 0; //elsewhere

答案 4 :(得分:0)

使用unlink

#include <unistd.h>

int unlink(const char *pathname); 
  

unlink()从中删除名称   文件系统。如果那个名字是最后一个   链接到文件,没有进程   打开文件的文件被删除了   它正在使用的空间   可以重复使用。

     

如果名称是a的最后一个链接   文件,但任何进程仍然有   文件打开文件将保留   直到最后一个文件存在   引用它的描述符已关闭。

     

如果名称指的是象征性的   链接已被删除。

     

如果名称引用了套接字,则为fifo   或设备删除它的名称   但是具有该对象的过程   open可以继续使用它。

答案 5 :(得分:0)

我认为您需要将“关闭文件”的概念扩展到fclosestd::fstream::close以外的任何内容。这可能就像

一样简单
class MyFile : public std::fstream {
  std::string filename;
public:
  MyFile(const std::string &fname) : std::fstream(fname), filename(fname) {}
  ~MyFile() { unlink(filename); }
}

或者它可能更复杂。据我所知,它甚至可能更简单 - 如果您只在代码中的一个或两个位置关闭文件,最好的办法可能是简单unlink那里的文件(或使用boost :: filesystem) ::删除,正如汤姆建议的那样。)

OTOH,如果您想要实现的是从您的进程启动的进程可以使用该文件,您可能根本不需要将它放在磁盘上。 fork ed进程继承打开的文件。不要忘记dup他们,以免在孩子中寻求影响父母的位置,反之亦然。