如何在 C++ 中关闭文件时删除该文件在 Linux 上?

发布于 2024-09-08 10:03:30 字数 92 浏览 3 评论 0原文

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

I wish for a file to be deleted from disk only when it is closed. Up until that point, other processes should be able to see the file on disk and read its contents, but eventually after the close of the file, it should be deleted from disk and no longer visible on disk to other processes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

野生奥特曼 2024-09-15 10:03:30

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

编辑:根据 WilliamKF 后来添加的评论,这不会实现他想要的 - 它会保留文件本身,直到它的所有句柄都关闭,但是文件的目录条目一旦您调用unlink/remove,名称就会消失。

Open the file, then delete it while it's open. Other processes will be able to use the file, but as soon as all handles to file are closed, it will be deleted.

Edit: based on the comments WilliamKF added later, this won't accomplish what he wants -- it'll keep the file itself around until all handles to it are closed, but the directory entry for the file name will disappear as soon as you call unlink/remove.

皓月长歌 2024-09-15 10:03:30

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

然后是磁盘文件的链接计数。全新文件的计数为一。计数由 link(2) 系统递增称呼。 unlink(2) 减少它。当此计数降至零时,文件将从文件系统中删除。

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

Open files in Unix are reference-counted. Every open(2) increments the counter, every close(2) decrements it. The counter is shared by all processes on the system.

Then there's a link count for a disk file. Brand-new file gets a count of one. The count is incremented by the link(2) system call. The unlink(2) decrements it. File is removed from the file system when this count drops to zero.

The only way to accomplish what you ask is to open the file in one process, then unlink(2) it. Other processes will be able to open(2) or stat(2) it between open(2) and unlink(2). Assuming the file had only one link, it'll be removed when all processes that have it open close it.

苄①跕圉湢 2024-09-15 10:03:30

使用 取消链接

#include <unistd.h>

int unlink(const char *pathname); 

unlink() 从
文件系统。如果这个名字是最后一个
链接到文件并且没有进程
文件打开 文件被删除并且
它所使用的空间已经形成
可重复使用。

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

如果名称引用了符号
链接已删除。

如果名称引用套接字,fifo
或设备名称已被删除
但具有该对象的进程
打开可以继续使用。

Use unlink

#include <unistd.h>

int unlink(const char *pathname); 

unlink() deletes a name from the
filesystem. If that name was the last
link to a file and no processes have
the file open the file is deleted and
the space it was using is made
available for reuse.

If the name was the last link to a
file but any processes still have the
file open the file will remain in
existence until the last file
descriptor referring to it is closed.

If the name referred to a symbolic
link the link is removed.

If the name referred to a socket, fifo
or device the name for it is removed
but processes which have the object
open may continue to use it.

李不 2024-09-15 10:03:30

不确定,但你可以尝试删除,但它看起来更像c -风格。

也许boost::filesystem::remove?

bool remove( const path & ph );

前提条件:!ph.empty()

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

后置条件:!exists( ph )

抛出:if ph.empty() || (存在(ph)
&& is_directory(ph) && !is_empty(ph))。
请参阅空路径基本原理。

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

基本原理:当
!exists( 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

Not sure, but you could try remove, but it looks more like c-style.

Maybe boost::filesystem::remove?

bool remove( const path & ph );

Precondition: !ph.empty()

Returns: The value of exists( ph )
prior to the establishment of the
postcondition.

Postcondition: !exists( ph )

Throws: if ph.empty() || (exists(ph)
&& is_directory(ph) && !is_empty(ph)).
See empty path rationale.

Note: Symbolic links are themselves
deleted, rather than what they point
to being deleted.

Rationale: Does not throw when
!exists( ph ) because not throwing:

Works correctly if ph is a dangling
symbolic link. Is slightly
easier-to-use for many common use
cases. Is slightly higher-level
because it implies use of
postcondition semantics rather than
effects semantics, which would be
specified in the somewhat lower-level
terms of interactions with the
operating system. There is, however, a
slight decrease in safety because some
errors will slip by which otherwise
would have been detected. For example,
a misspelled path name could go
undetected for a long time.

The initial version of the library
threw an exception when the path did
not exist; it was changed to reflect
user complaints.

You could create a wrapper class that counts references, using one of the above methods to delete 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
沒落の蓅哖 2024-09-15 10:03:30

我认为您需要将“关闭文件”的概念扩展到 fclose 或 std::fstream::close 之外的任何您打算做的事情。这可能很简单,

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

也可能更复杂。据我所知,它甚至可能要简单得多 - 如果您仅在代码中的一两个位置关闭文件,最好的办法可能是简单地取消链接那里的文件(或使用 boost ::filesystem::remove,正如汤姆建议的那样)。

OTOH,如果您想要实现的是从您的进程启动的进程可以使用该文件,您可能根本不需要将其保留在磁盘上。 分叉进程继承打开的文件。不要忘记重复它们,以免子级中的查找影响父级中的位置,反之亦然。

I think you need to extend your notion of “closing the file” beyond fclose or std::fstream::close to whatever you intend to do. That might be as simple as

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

or it may be something much more elaborate. For all I know, it may even be much simpler – if you close files only at one or two places in your code, the best thing to do may be to simply unlink the file there (or use boost::filesystem::remove, as Tom suggests).

OTOH, if all you want to achieve is that processes started from your process can use the file, you may not need to keep it lying around on disk at all. forked processes inherit open files. Don't forget to dup them, lest seeking in the child influences the position in the parent or vice versa.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文