我似乎对文件删除如何在Linux上运行感到困惑(在Mac OS X上的行为相同)。以下代码写入1GB文件,然后立即删除它。它这样做了1024次。我认为,由于文件已关闭,它将立即被删除(空间回收,甚至可能回收文件描述符)。相反,如果我查看lsof
,该文件仍然声明为该进程所拥有(附加(删除))。如果我查看df
,该空间仍然用完了。最终,这个过程会因耗尽允许打开的文件数量,我可以提出的限制,或者只是耗尽空间而死亡。
这样做的正确方法是什么?我可以在进程终止之前删除文件(并回收它的空间),或者这是一个绝望的练习,我的代码需要另一种设计吗?
#include <unistd.h>
#include <cstdlib>
#include <cstdio>
#include <fcntl.h>
#include <iostream>
int main()
{
size_t n = 1024*1024*1024;
void* buffer = malloc(n);
std::cout << "Buffer created" << std::endl;
for (unsigned i = 0; i < 1024; ++i)
{
char filename[50] = "STORAGE.XXXXXX";
mkstemp(filename);
std::cout << filename << std::endl;
int fh = open(filename, O_WRONLY | O_SYNC, 0600);
write(fh, buffer, n);
close(fh);
remove(filename);
}
free(buffer);
sleep(60);
}
lsof的:
test-remo 29251 ... 3u REG 8,51 1073741824 9307914 .../tmp/STORAGE.Tyj4oG (deleted)
test-remo 29251 ... 4u REG 8,51 1073741824 9308254 .../tmp/STORAGE.fBkF5b (deleted)
test-remo 29251 ... 5u REG 8,51 1073741824 9308030 .../tmp/STORAGE.xfJ9P0 (deleted)
test-remo 29251 ... 6u REG 8,51 1073741824 9308538 .../tmp/STORAGE.0C6oea (deleted)
test-remo 29251 ... 7u REG 8,51 1073741824 9306147 .../tmp/STORAGE.w9dPzC (deleted)
test-remo 29251 ... 8u REG 8,51 1073741824 9308311 .../tmp/STORAGE.mIwcpq (deleted)
test-remo 29251 ... 9u REG 8,51 1073741824 9309004 .../tmp/STORAGE.srTZfy (deleted)
test-remo 29251 ... 10u REG 8,51 1073741824 9309284 .../tmp/STORAGE.xjQQ4Y (deleted)
test-remo 29251 ... 11u REG 8,51 1073741824 9309291 .../tmp/STORAGE.ioyPxI (deleted)
test-remo 29251 ... 12u REG 8,51 1073741824 9307415 .../tmp/STORAGE.saYo2L (deleted)
test-remo 29251 ... 13u REG 8,51 1073741824 9307810 .../tmp/STORAGE.ylW467 (deleted)
test-remo 29251 ... 14u REG 8,51 1073741824 9308666 .../tmp/STORAGE.lUYnWN (deleted)
test-remo 29251 ... 15u REG 8,51 1073741824 9309678 .../tmp/STORAGE.1rZM4M (deleted)
test-remo 29251 ... 16u REG 8,51 1073741824 9309702 .../tmp/STORAGE.wdggra (deleted)
test-remo 29251 ... 17u REG 8,51 1073741824 9309687 .../tmp/STORAGE.qczYAS (deleted)
test-remo 29251 ... 18u REG 8,51 1073741824 9309732 .../tmp/STORAGE.u0IxKV (deleted)
test-remo 29251 ... 19u REG 8,51 1073741824 9309708 .../tmp/STORAGE.6SiMpi (deleted)
test-remo 29251 ... 20u REG 8,51 1073741824 9308649 .../tmp/STORAGE.URky5Z (deleted)
test-remo 29251 ... 21u REG 8,51 1073741824 9309740 .../tmp/STORAGE.j8wEq2 (deleted)
test-remo 29251 ... 22u REG 8,51 1073741824 9309677 .../tmp/STORAGE.Wj5rco (deleted)
test-remo 29251 ... 23u REG 8,51 1073741824 9309828 .../tmp/STORAGE.I38ln3 (deleted)
test-remo 29251 ... 24u REG 8,51 1073741824 9309839 .../tmp/STORAGE.ent8I1 (deleted)
test-remo 29251 ... 25u REG 8,51 1073741824 9309843 .../tmp/STORAGE.1361nk (deleted)
test-remo 29251 ... 26u REG 8,51 1073741824 9309824 .../tmp/STORAGE.ue2WkW (deleted)
test-remo 29251 ... 27u REG 8,51 1073741824 9312037 .../tmp/STORAGE.4MdKsR (deleted)
test-remo 29251 ... 28u REG 8,51 1073741824 9312042 .../tmp/STORAGE.EgDft5 (deleted)
test-remo 29251 ... 29u REG 8,51 1073741824 9312059 .../tmp/STORAGE.NRcqlE (deleted)
test-remo 29251 ... 30u REG 8,51 1073741824 9309847 .../tmp/STORAGE.cF9qYw (deleted)
test-remo 29251 ... 31u REG 8,51 1073741824 9312103 .../tmp/STORAGE.wzfhSI (deleted)
test-remo 29251 ... 32u REG 8,51 1073741824 9312120 .../tmp/STORAGE.hfdv1d (deleted)
test-remo 29251 ... 33u REG 8,51 1073741824 9312090 .../tmp/STORAGE.kSX2D4 (deleted)
test-remo 29251 ... 34u REG 8,51 1073741824 9309813 .../tmp/STORAGE.FWKVGf (deleted)
test-remo 29251 ... 35u REG 8,51 1073741824 9312148 .../tmp/STORAGE.CYPGGL (deleted)
test-remo 29251 ... 36u REG 8,51 1073741824 9312171 .../tmp/STORAGE.it4bmC (deleted)
test-remo 29251 ... 37u REG 8,51 1073741824 9312145 .../tmp/STORAGE.IGSzVO (deleted)
test-remo 29251 ... 38u REG 8,51 1073741824 9312228 .../tmp/STORAGE.CMSOil
答案 0 :(得分:1)
当您调用mkstemp
时,它不仅会创建一个临时文件,还会打开它并返回一个文件句柄。
#include <unistd.h>
#include <cstdlib>
#include <cstdio>
#include <fcntl.h>
#include <iostream>
int main()
{
size_t n = 1024*1024*1024;
void* buffer = malloc(n);
std::cout << "Buffer created" << std::endl;
for (unsigned i = 0; i < 1024; ++i)
{
char filename[50] = "STORAGE.XXXXXX";
int fh;
fh = mkstemp(filename);
// close(fh)
std::cout << filename << std::endl;
// fh = open(filename, O_WRONLY | O_SYNC, 0600);
write(fh, buffer, n);
close(fh);
remove(filename);
}
free(buffer);
sleep(60);
}
如果你想用WRONLY和SYNC打开它,那么你必须先关闭返回的文件句柄,然后重新打开它,如果你愿意的话。在这种情况下,只需删除//
和close
之前的open
注释标记,或使用mkostemp
代替。
NAME
mkstemp, mkostemp, mkstemps, mkostemps - create a unique temporary file
SYNOPSIS
#include <stdlib.h>
int mkstemp(char *template);
int mkostemp(char *template, int flags);
RETURN VALUE
On success, these functions return the file descriptor of the temporary file.
On error, -1 is returned, and errno is set appropriately.