问题
问题依然来源于参与的项目。参加产品的开发已有一年多的时间。项目过程中每周都会由SEG讨论一个星期内产品在客户使用过程中遇到的问题。最近的几次讨论总是围绕着我们的程序产生的临时文件。
由于程序运行过程中有些数据需要借助于文件形式进行转换,或需要临时保存下来,供稍后使用。在我们的程序运行过程中产生了可怕的问题,用户发现临时目录越来越占居磁盘空间(数据不断增加)~~
也许部分人会认为,这不是程序的错误,临时文件可以让用户去手动删除,就像微软的操作系统一样,偶尔需要用户去释放一下系统空间。我想我们的程序应该尽量减轻用户的负担,这样用户才会乐于使用我们的产品,更何况部署在服务器网关的产品。
作为临时文件,其应该被删除。检查我们的代码,发现逻辑上是正确的:1)创建文件;2)使用文件; 3)删除文件。那么为什么还会有临时文件存在呢?不是已经被删除了么?
解决方法
经过大家的讨论发现,如果程序在还没有删除之前,程序进程被用户强行杀掉(亦或程序crash),那么删除动作就不会发生了,临时文件就会留下成为永久文件。那么如何解决这类问题呢?
方法一:大家讨论之后决定在程序进入创建临时文件时,检查存在的废旧临时文件,并且删除它们。逻辑如下:
1)检查过时临时文件; 2)删除过时临时文件 ; 3)创建临时文件; 4)使用文件; 5)删除文件。
这样的程序逻辑看上去更严谨一点,当然,也解决了遇到的问题。
那么有没有其他办法呢?
方法二:我们可以通过去除文件的连接,来使得系统自动删除文件数据。这需要我们的程序员对我们的操作系统有一定的了解,了解系统是如何去管理我们创建的文件(见文中附加内容)。
那么对于连接数为0的文件,系统kernel将会删除其所有数据~所以,我们可以将创建的临时文件的连接数设置为0,如此一来就不必担心临时文件会不小心遗留下来~
下面是一段示例代码:
-
#include <iostream>
-
#include <unistd.h>
-
#include <sys/types.h>
-
#include <fcntl.h>
-
-
using namespace std;
-
-
int main(int argc, char *argv[])
-
{
-
-
char *file = "/tmp/rc.bak"; //temp file to be written
-
-
//open/create file
-
int fd = open(file, O_RDWR | O_CREAT | O_TRUNC);
-
if(fd < 0)
-
{
-
cout<<"Open file failed!"<<endl;
-
}
-
-
//unlink file
-
int code = unlink(file);
-
if(code < 0)
-
{
-
cout<<"Unlink file failed!"<<endl;
-
}
-
-
//write something...
-
cout<<"Do other thing...."<<endl;
-
ssize_t n = write(fd, "abcdef",6);
-
sleep(3);
-
-
//read from the temp file
-
lseek(fd, 0, SEEK_SET);
-
char buffer[256];
-
-
ssize_t count = read(fd, buffer, 256);
-
buffer[count] = '\0';
-
cout<<buffer<<endl;
-
-
code = close(fd);
-
if(code < 0)
-
{
-
cout<<"Close file failed!"<<endl;
-
}
-
return 0;
-
}
在这段代码中,主要分为以下几步:
1)创建rc.bak文件;
2)使用unlink,删除rc.bak的连接;
3)通过fd写读该临时文件;
4)关闭fd;
不管程序是自己运行结束还是被强行终止,在/tmp目录下,均不会存在该临时文件。
若注释掉21~25行,则如下图所示:
So, kernel will delete the content of this file (the process either closes the file or terminates).
附加
知识:
在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都会分配一个编号(索引节点号)。在Linux中,多个文件名可以指向同一索引节点,称之为硬连接。硬连接的作用本质上是允许一个文件拥有多个有效路径名,用户打开任何一个文件,其指向的数据部分均是相同。当一个文件有多个连接时,删除其中一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。
关于连接:
下图中,建立连接ma.cpp的连接another,可以看到两个文件的连接数均变为2(红色部分),此时已不能区分出哪个是原始文件(因为这两个是完全等同的连接)。
删除一个连接(删除another)后,连接数将会减1。
对于新创建的文件,连接数总是为1。
|
阅读(934) | 评论(0) | 转发(0) |