这两天测试文件操作的性能,发现了有的地方打开文件后没有关闭。不关闭文件的后果是比较严重的,尤其是对服务器端程序来说更为严重。那这样会有什么问题呢?
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% /