Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用文件描述符在C中删除文件?_C_Linux_File_File Descriptor - Fatal编程技术网

如何使用文件描述符在C中删除文件?

如何使用文件描述符在C中删除文件?,c,linux,file,file-descriptor,C,Linux,File,File Descriptor,在我的代码中,我使用mkstemp()函数(Linux上的Im)创建了一个具有随机名称的文件。此函数返回的是int作为文件描述符 intfd; char temp[]=“tempXXXXXX”; fd=mkstemp(温度); 稍后,我可以使用fdopen()通过int文件描述符访问该文件 FILE*FILE_ptr=NULL; 文件_ptr=fdopen(fd); 但在我的程序结束时,我想看看该文件是否仍然存在,并带有我创建它时给出的随机名称(如果成功,程序应该更改该文件名)。如果在该文件

在我的代码中,我使用
mkstemp()
函数(Linux上的Im)创建了一个具有随机名称的文件。此函数返回的是
int
作为
文件描述符

intfd;
char temp[]=“tempXXXXXX”;
fd=mkstemp(温度);
稍后,我可以使用
fdopen()
通过
int
文件描述符访问该文件

FILE*FILE_ptr=NULL;
文件_ptr=fdopen(fd);
但在我的程序结束时,我想看看该文件是否仍然存在,并带有我创建它时给出的随机名称(如果成功,程序应该更改该文件名)。如果在该文件上运行的
rename()
函数成功,我可以设置一个标志,但当我只有它的文件描述符时,我仍然不知道如何删除它

if rename files=>删除临时文件

我该怎么做?或者如果我有
文件描述符
,是否有办法获取文件名?

readlink
如果您使用路径
/proc/self/fd/
添加fd,则根据文件描述符向您提供文件名

然后使用
remove
删除传递给您的名称
readlink
的文件

ssize\u t readlink(const char*path,char*buf,size\u t bufsiz)(同时加载
ernno

int-remove(常量字符*文件名)(成功返回零,否则返回非零)

我希望这样的事情能帮助你


⚠ 不要复制/超过此文件,您必须编辑“文件名”_缓冲区,_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;
}
#包括
#包括
#包括
int delete_文件(int fd){
char*str_fd=itoa(fd,str_fd,10);
char*path=strcat(“/proc/self/fd/”,str_fd);
if(读取链接(路径、缓冲区、bufsize)=-1)
返回-1;
int del=删除(文件名);
如果(!del)
printf(“文件删除成功”);
其他的
printf(“文件未被删除”);
返回0;
}

(请随意编辑这个代码,我没有测试代码,我给了汉德尔缓冲区和缓冲区大小)

,即使这不能完全回答你问的关于代码> MKSTEMP<代码>的问题,考虑创建一个自动删除的临时文件,除非你重命名它。< /P> 与
mkstemp
不同,您可以调用
open
并结合创建标志
O_TMPFILE
来创建一个临时的未命名文件,该文件在关闭时自动删除

见:

您可以使用您希望放置临时文件的路径来调用open,而不是文件名,如:

temp_fd = open("/path/to/dir", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
如果要为临时文件指定一个永久位置/名称,您可以稍后在其上调用
linkat

linkat(temp_fd, NULL, AT_FDCWD, "/path/for/file", AT_EMPTY_PATH);
注意:O_TMPFILE
需要文件系统支持,但主流Linux文件系统确实支持它。

C和POSIX(因为您使用的是POSIX库函数)都没有定义通过打开的文件描述符删除文件的方法。这是有道理的,因为你所说的删除实际上是删除一个目录条目,而不是文件本身。同一个文件可以在多个位置以多个名称硬链接到目录树中。在从目录树中删除指向数据的最后一个硬链接且不再有任何进程将其打开后,操作系统负责从存储器中删除数据,或至少将其标记为可供重用

文件描述符直接与文件关联,而不是与任何特定路径关联,尽管在许多情况下,您可以通过路径获得一个文件描述符。这有几个后果,其中之一是一旦进程打开一个文件,就无法通过操纵目录树将该文件从其下拉出。这就是解决问题的标准方法之一的基础:在打开它之后立即取消链接(删除),然后再丢失它的名称。例如:

#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;
}
#包括
#包括
int make_temp_文件(){
char filename[]=“我的临时文件\uxxxxxx”;
int-fd;
fd=mkstemp(文件名);
如果(fd==-1){
//处理打开失败。。。
}否则{
//文件已成功打开,现在取消链接
int result=unlink(文件名);
//…检查并处理错误情况。。。
}
返回fd;
}

这不仅(几乎)确保了临时文件不会过期,而且还阻止了用户和进程访问其所属进程未明确授予访问权限的内容。

这是否回答了您的问题@KamilCuk
unlink
需要一个文件名,而
mkstemp
没有提供。我认为您不能。删除的是名称,而不是文件。一个文件可能有多个名称,也可能没有-Linux如何知道要删除哪个名称?
mkstemp
已经有文件名-它是
mkstemp(char*template)
。只是
mkstemp(模板);取消链接(模板)
@John mkstemp修改模板字符串,以便返回文件名。我不知道为什么它不识别
O_TEMPFILE
标志,是否应该有什么东西代替“AT_EMPTY_PATH”?@John well。。。s/e//应该有什么类型的缓冲区?以下划线和大写字母开头的名称,如
\u buffer
\u BUFSIZE
,是保留标识符,不应在代码中使用。看@john这是一个字符*
#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;
}