如何使用文件描述符删除 C 中的文件?
How to delete a file in C using a file-descriptor?
在我的代码中,我使用 mkstemp()
函数创建了一个随机名称的文件(我在 Linux 上)。这个函数 returns 是一个 int
是一个 file descriptor
.
int fd;
char temp[] = "tempXXXXXX";
fd = mkstemp(temp);
稍后我可以通过 int
文件描述符使用 fdopen()
访问该文件。
FILE *file_ptr = NULL;
file_ptr = fdopen(fd);
但在我的程序结束时,我想看看该文件是否仍然存在,并使用我创建它时给定的随机名称(如果成功,程序应该更改该文件名)。如果该文件上的 rename()
函数 运行 成功,我可以设置一个标志,但是当我只有它的文件描述符时,我仍然不知道如何删除它。
if rename files => remove the temp file
我该怎么做?或者如果我有 file descriptor
?
是否有办法获取文件名
readlink
如果您使用路径 /proc/self/fd/
添加 fd,则根据文件描述符为您提供文件名。
然后使用 remove
删除传递名称 readlink
给你的文件
ssize_t readlink(const char *path, char *buf, size_t bufsiz);
(也加载ernno
)
int remove(const char *filename);
(returns零成功,否则非零)
我希望这样的事情能帮到你?
⚠ 不要copy/past 这个你必须编辑“文件名”; _BUFFER, _BUFSIZE ⚠
#include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
int delete_file(int fd) {
char *str_fd = itoa(fd, str_fd, 10);
char *path = strcat("/proc/self/fd/", str_fd);
if (read_link(path, buffer, bufsize) == -1)
return -1;
int del = remove(filename);
if (!del)
printf("The file is Deleted successfully");
else
printf("The file is not Deleted");
return 0;
}
(随意编辑这个,我没有测试代码,我让你处理缓冲区和缓冲区大小)
即使这不能完全回答您提出的关于 mkstemp
的问题,请考虑创建一个将自动删除的临时文件,除非您重命名它。
您可以调用 open
并结合创建标志 O_TMPFILE
来创建一个临时的、未命名的文件,该文件在文件关闭时自动删除。
见open(2):
O_TMPFILE (since Linux 3.11)
Create an unnamed temporary regular file. The pathname argu‐
ment specifies a directory; an unnamed inode will be created
in that directory's filesystem. Anything written to the
resulting file will be lost when the last file descriptor is
closed, unless the file is given a name.
您可以使用您希望放置临时文件的路径调用 open,而不是文件名,例如:
temp_fd = open("/path/to/dir", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
如果你想给临时文件一个永久的location/name,你可以稍后调用linkat
:
linkat(temp_fd, NULL, AT_FDCWD, "/path/for/file", AT_EMPTY_PATH);
注意: O_TMPFILE
需要文件系统支持,但主流 Linux 文件系统支持它。
C 和 POSIX(因为您使用的是 POSIX 库函数)都没有定义通过打开的文件描述符删除文件的方法。这是有道理的,因为您所说的删除实际上是删除目录条目,而不是文件本身。同一个文件可以硬 linked 到目录树的多个位置,具有多个名称。 OS 负责从存储中删除其数据,或者至少将其标记为可重用,在最后一个硬 link 从目录树中删除并且不再有进程打开它之后.
文件描述符直接与文件相关联,而不是与任何特定路径相关联,尽管在许多情况下,您可以通过路径获得文件描述符。这有几个后果,其中一旦进程打开一个文件,就不能通过操纵目录树从它下面拉出该文件。这是解决您的问题的一种标准方法的基础:unlink(删除)打开它后立即丢失它的名字。示例:
#include <stdlib.h>
#include <unistd.h>
int make_temp_file() {
char filename[] = "my_temp_file_XXXXXX";
int fd;
fd = mkstemp(filename);
if (fd == -1) {
// handle failure to open ...
} else {
// file successfully opened, now unlink it
int result = unlink(filename);
// ... check for and handle error conditions ...
}
return fd;
}
这不仅(几乎)确保临时文件不会超过它的需要,而且还可以防止拥有进程未明确授予访问权限的用户和进程访问内容。
在我的代码中,我使用 mkstemp()
函数创建了一个随机名称的文件(我在 Linux 上)。这个函数 returns 是一个 int
是一个 file descriptor
.
int fd;
char temp[] = "tempXXXXXX";
fd = mkstemp(temp);
稍后我可以通过 int
文件描述符使用 fdopen()
访问该文件。
FILE *file_ptr = NULL;
file_ptr = fdopen(fd);
但在我的程序结束时,我想看看该文件是否仍然存在,并使用我创建它时给定的随机名称(如果成功,程序应该更改该文件名)。如果该文件上的 rename()
函数 运行 成功,我可以设置一个标志,但是当我只有它的文件描述符时,我仍然不知道如何删除它。
if rename files => remove the temp file
我该怎么做?或者如果我有 file descriptor
?
readlink
如果您使用路径 /proc/self/fd/
添加 fd,则根据文件描述符为您提供文件名。
然后使用 remove
删除传递名称 readlink
给你的文件
ssize_t readlink(const char *path, char *buf, size_t bufsiz);
(也加载ernno
)
int remove(const char *filename);
(returns零成功,否则非零)
我希望这样的事情能帮到你?
⚠ 不要copy/past 这个你必须编辑“文件名”; _BUFFER, _BUFSIZE ⚠
#include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
int delete_file(int fd) {
char *str_fd = itoa(fd, str_fd, 10);
char *path = strcat("/proc/self/fd/", str_fd);
if (read_link(path, buffer, bufsize) == -1)
return -1;
int del = remove(filename);
if (!del)
printf("The file is Deleted successfully");
else
printf("The file is not Deleted");
return 0;
}
(随意编辑这个,我没有测试代码,我让你处理缓冲区和缓冲区大小)
即使这不能完全回答您提出的关于 mkstemp
的问题,请考虑创建一个将自动删除的临时文件,除非您重命名它。
您可以调用 open
并结合创建标志 O_TMPFILE
来创建一个临时的、未命名的文件,该文件在文件关闭时自动删除。
见open(2):
O_TMPFILE (since Linux 3.11)
Create an unnamed temporary regular file. The pathname argu‐
ment specifies a directory; an unnamed inode will be created
in that directory's filesystem. Anything written to the
resulting file will be lost when the last file descriptor is
closed, unless the file is given a name.
您可以使用您希望放置临时文件的路径调用 open,而不是文件名,例如:
temp_fd = open("/path/to/dir", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
如果你想给临时文件一个永久的location/name,你可以稍后调用linkat
:
linkat(temp_fd, NULL, AT_FDCWD, "/path/for/file", AT_EMPTY_PATH);
注意: O_TMPFILE
需要文件系统支持,但主流 Linux 文件系统支持它。
C 和 POSIX(因为您使用的是 POSIX 库函数)都没有定义通过打开的文件描述符删除文件的方法。这是有道理的,因为您所说的删除实际上是删除目录条目,而不是文件本身。同一个文件可以硬 linked 到目录树的多个位置,具有多个名称。 OS 负责从存储中删除其数据,或者至少将其标记为可重用,在最后一个硬 link 从目录树中删除并且不再有进程打开它之后.
文件描述符直接与文件相关联,而不是与任何特定路径相关联,尽管在许多情况下,您可以通过路径获得文件描述符。这有几个后果,其中一旦进程打开一个文件,就不能通过操纵目录树从它下面拉出该文件。这是解决您的问题的一种标准方法的基础:unlink(删除)打开它后立即丢失它的名字。示例:
#include <stdlib.h>
#include <unistd.h>
int make_temp_file() {
char filename[] = "my_temp_file_XXXXXX";
int fd;
fd = mkstemp(filename);
if (fd == -1) {
// handle failure to open ...
} else {
// file successfully opened, now unlink it
int result = unlink(filename);
// ... check for and handle error conditions ...
}
return fd;
}
这不仅(几乎)确保临时文件不会超过它的需要,而且还可以防止拥有进程未明确授予访问权限的用户和进程访问内容。