这两天测试文件操作的性能,发现了有的地方打开文件后没有关闭。不关闭文件的后果是比较严重的,尤其是对服务器端程序来说更为严重。那这样会有什么问题呢?
1.不能再打开新文件.
打开大量文件并且不关闭, 很快会达到进程最大允许打开的文件数限制,这样就不能再打开文件。
在Linux上,可以通过ulimit -n 来查看和更改当前session的限制数,比如在我的机器上是:
$ ulimit -n 7168 $ ulimit -n 10000 10000
也可以通过修改/etc/security/limits.conf来永久性的修改限制数
2. 硬盘空间被占满。
如果文件被打开后,再被删除,在文件不被关闭的情况下,原文件占用的空间不会被释放,这样可能会出现磁盘空间不足的问题。我碰到的实际例子是 “安全删除文件”: 先将文件全部内容填充为0,再删除文件。问题是在把文件内容填充为0后没有关闭文件,所以虽然文件在后面被删除了,但由于是服务器端程序,进程不会终止,所以空间并没有被释放。
下面摘自于unlink函数的manual:
unlink() deletes a name from the file system. If that name was the
last link to a file and no processes have the file open the file is
deleted and the space it was using is made available for reuse.If the name was the last link to a file but any processes still have
the file open the file will remain in existence until the last file
descriptor referring to it is closed.
下面这个程序可以对这一点进行测试:
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
int main(int argc, char** argv){
if(argc < 3){
printf("Copy a file to target, then delete the target file without close"
"Usage: %s <filename> <target filename>n", argv[0]);
return -1;
}
int size;
char* buf = malloc(1024 * 16);
FILE *fp = fopen(argv[1], "r");
FILE *fp2 = fopen(argv[2], "w+");
do {
size = fread(buf, 1, 1024*16, fp);
fwrite(buf, 1, size, fp2);
} while(!feof(fp));
free(buf);
fclose(fp);
remove(argv[2]);
printf("Press Ctrl +c to stop the program.n");
while(1){
sleep(100);
}
return 0;
}
测试步骤:
找一个比较大的测试文件,以LibreOffice_4.1.0_Linux_x86-64_rpm.tar.gz 为例
$ ls -lh LibreOffice_4.1.0_Linux_x86-64_rpm.tar.gz -rw-rw-r-- 1 twer twer 198M Sep 5 12:36 LibreOffice_4.1.0_Linux_x86-64_rpm.tar.gz $ df /dev/sda1 Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda1 464250648 45744328 394923704 11% /
在一个新的命令行窗口上执行测试程序
$ ./a.out LibreOffice_4.1.0_Linux_x86-64_rpm.tar.gz t/libreoffice.tar.gz Press Ctrl +c to stop the program.
再查看当前的分区使用情况
$ df /dev/sda1 Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda1 464250648 45946800 394721232 11% /
通过Ctrl + c 关闭测试程序, 再查看当前的分区使用情况
$ df /dev/sda1 Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda1 464250648 45744328 394923704 11% /