曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 5618|回复: 1
打印 上一主题 下一主题

[文件I/O] unlink

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2009-4-19 18:27:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
函数功能
删除掉名字和这个名字所指向的文件

函数原型
#include <unistd.h>

int unlink(const char *pathname):

描述
unlink() 从文件系统中删除掉一个名字。如果这个名字所链接的文件没有被任何进程所打开,那么这个文件将被删除。此文件之前所占用的空间可以被再次使用。
如果这个名字所链接的文件仍被进程所打开,那么此文件直到指向它的文件描述符关闭后方才被删除。

测试代码
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

int main()
{
    int file_desc;
   
    file_desc = open("/tmp/LCK.unlink.test", O_RDWR | O_CREAT | O_EXCL, 0444);
    if (file_desc == -1) {
        printf(" File already exist !\n");
        exit(EXIT_SUCCESS);
    } else {
        printf(" Open succeeded..now for 5s and unlink it and open again\n");
        sleep(5);
        unlink("/tmp/LCK.unlink.test");
        printf(" unlink have done....,open again..\n");
        file_desc = open("/tmp/LCK.unlink.test", O_RDWR | O_CREAT | O_EXCL, 0444);
        if (file_desc == -1) {
            printf(" unlink failure \n");
            exit(EXIT_SUCCESS);
        } else {
            printf("unlink succeeded\n");
            exit(EXIT_SUCCESS);
        }
    }
    exit(EXIT_SUCCESS);
}
说明
先创建一个文件,然后 5 秒后将其删除,再创建。

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
沙发
 楼主| 发表于 2009-7-30 18:49:59 | 只看该作者

再看 unlink

unlink() 一个文件有时会造成一种假象,文件好像明明已经被删除了,但从实际的运作工程中,文件似乎却又是存在的。利用这种 “假象”,可以做创建一些临时用的文件,这些文件在程序结束,或者等待关闭文件描述符时,才会真正的删除。这样的例子见:http://www.groad.net/bbs/read.php?tid=980
在 上面链接的实例中,创建了特定于客户端的 FIFO 文件,为了在程序结束时这些 FIFO 也会随之删除,而在程序未结束时仍然可以使用这些文件,其中使用了 unlink() 函数达到此目的。之前,这个问题也困扰了我一会,当时的思考方向是,为什么文件都被删除了,但进程间还能通讯?难道只是两个进程间只要互相知道了各自已打开中间文件的文件描述符后,即使是这个中间文件被删除了还能利用得到的文件描述符进行通讯?后来,才知道这种想法是错误的,实质原因正是因为用了 unlink() 的缘故。

下面有两个测试代码,一个负责读一个文件,一个负责写一个文件,还有一个中间文件 test.txt ,里面随便填写些什么内容或者为空。这两个程序当时是为了做实验,需要 GDB 进行单步调试观察,而不能全速运行查看结果。

测试代码-1-read_test.c :
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main (void)
{
    char buf [128];
    int fd;
    int sndfd;
    int n;

    if ((fd = open ("test.txt", O_RDONLY)) == -1) {
        perror("open");
        exit(1);
    }
    buf [0] = (char)fd;

    mkfifo ("send_fifo", 0777);
   
    sndfd = open ("send_fifo", O_WRONLY);

    write (sndfd, buf, 1);

    unlink ("test.txt");

    n = read (fd, buf, 128);
    buf [n] = '\\0';
   
    printf ("%s\\n", buf);

    close (fd);
    unlink ("send_fifo");
   
   
    return (0);
}
测试代码-2-write_test.c
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main (void)
{
    int fd;
    char buf [10];
    char buffer [128] = "hello world";
    int  revfd;

    if ((fd = open ("test.txt", O_WRONLY)) == -1) {
        perror("write");
        exit(1);
    }
       
    revfd = open ("send_fifo", O_RDONLY);

    read (revfd, buf, 1);    /*得到客户机对test.txt的文件描述符*/
   

    write ((int)buf[0], buffer, 128);

    close (fd);

    return 0;
}
生成程序后,分别用 GDB 进行单步调试。当然这两个程序的目的是为了测试,证明之前 “文件已经删除,但利用业已打开的文件描述符也能进行进程间的通讯” 的错误想法!

在 read_test.exe 程序中,建立了一个 FIFO ,把打开 test.txt 后得到的文件描述符发送给 write_test.exe 。write_test.exe 接收到后,再返回到 read_test.exe 中,单步跟下,调用 unlink() 删除 test.txt 文件。这里注意,在步过unlink() 这个函数后,在另外一个终端窗口里用 ls 命令查看 test.txt 是否存在,可以看到命令的结果是找不到有此文件,但实际上这个文件本身并没有真正的删除,只是它的名字已经从目录条目表中被隔去,而 ls 命令查看文件就列出目录条目表中的条目信息( 目录下的文件名字 )。
最后,用 wite_test.exe 写一个 hello world ,然后用 read_test.exe 接收,一开始造成的疑惑出现了---"命名用 ls 命令查看不到文件所在,而这个 hello world 却仍然被 read_test.exe 接收到了!“实际情况是,read_test.exe 用 read() 读取到的内容仍然是来自 test.txt 。test.txt 真正被删除是两个程序都结束的时候!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-4 14:47 , Processed in 0.082870 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表