Linux創造固定的檔案大小-預分配磁碟空間
阿新 • • 發佈:2018-10-31
一、課前預習
寫本篇文章的目的很簡單,防止採坑、防止採坑、防止採坑
我們在開發程式的過程中,往往需要預分配磁碟空間,防止因磁碟空間不夠而引發程式異常問題(已踩過坑), 現網查閱資料,有些預分配磁碟空間的方法不正確,在這裡特別記錄一下, 除此之外,把正確的預分配的方法和大家分享一下,如果其他人有建議,歡迎拍磚狠砸
二、假:磁碟預分配---ftruncate
1. 使用lseek、ftruncate到一個固定位置生成的“空洞檔案”是不會佔據真正的磁碟空間的。
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <stdint.h> uint64_t file_size = 10*1024*1024*1024ULL; int main() { int fd = -1; fd = open("test.data.fruncate.txt", O_RDWR | O_CREAT, 0666); if(fd < 0){ printf("open failed\n"); return -1; } if(ftruncate(fd, file_size)){ printf("ftruncate error\n"); return -1; } lseek(fd, file_size - 1,SEEK_CUR); write(fd, "1", 1); close(fd); return 0; }
測試結果
2. fseek fputs填充檔案的最後一個位元組
#include <stdio.h>
#include <unistd.h>
int main()
{
FILE *f = fopen("test.data", "w");
fseek(f, 256*1024*1024 - 1, SEEK_CUR);
fputc(0,f);
return 0;
}
3. dd命令
dd if=/dev/zero of=test bs=1M count=0 seek=1024
測試結果
4. 額外補充:
1 .ls顯示檔案的“邏輯上”的size, 這不是檔案真正佔用磁碟空間大小,這部分空間也會被其他程序使用。
2 .du顯示檔案“物理上”的size,即du顯示的size是檔案在硬碟上佔據了多少個block計算出來的
三、真:磁碟預分配---fallocate
1. 使用fallocate 或者posix_fallocate函式
請求tlinux核心大神後,原來還存在fallocate 和 posix_fallocate這樣的函式, 還是自己太low, 其實fallocate 和 posix_fallocate兩個最大的區別:
This is a nonportable, Linux-specific system call
廢話也不多說, 還是直接上程式碼比較好一點, 一目瞭然
#define _GNU_SOURCE /* See feature_test_macros(7) */ #include <fcntl.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <string.h> #include <stdint.h> uint64_t file_size = 10*1024*1024*1024ULL; //int fallocate(int fd, int mode, off_t offset, off_t len); //int posix_fallocate(int fd, off_t offset, off_t len); int main() { int fd = -1; int ret = -1; fd = open("tmp.txt", O_CREAT|O_RDWR, 0666); if(fd < 0){ printf("fd < 0"); return -1; } //ret = fallocate(fd, 0, 0, file_size); ret = posix_fallocate(fd, 0, file_size); if(ret < 0 ){ printf("ret = %d, errno = %d, %s\n", ret, errno, strerror(errno)); return -1; } printf("fallocate create %.2fG file\n", file_size/1024/1024/1024.0); close(fd); return 0; }
測試結果:
[email protected]:/data6#time ./posix_fallocate
fallocate create 10.00G file
real 0m0.014s
user 0m0.000s
sys 0m0.014s
[email protected]:/data6#ll -h posix_fallocate.file.txt
-rw-r--r-- 1 root root 10G Oct 25 15:45 posix_fallocate.file.txt
[email protected]:/data6#du -sh posix_fallocate.file.txt
11G posix_fallocate.file.txt
不僅可以佔住空間,而且速度非常快, 之前有過一個愚蠢的想法, 用dd命令直接建立10G檔案,但是會造成IO毛刺,肯定不能這麼玩,要是創造100G檔案豈不是涼涼了。dd命令還是安安靜靜壓測下磁碟效能或者創造一些小檔案比較好。
2. 額外補充
- 磁碟空間預分配,不是所有linux系統都支援,有時候就分配失敗,這就沒有辦法了。如下
ret = -1, errno = 95, Operation not supported
- linux命令磁碟預分配---fallocate
[email protected]:/data6#fallocate -l 10G 2.txt [email protected]:/data6#ll -h 2.txt -rw-r--r-- 1 root root 10G Oct 25 15:33 2.txt [email protected]:/data6#du -sh 2.txt 11G 2.txt