溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Linux創(chuàng)造固定的文件大小-預(yù)分配磁盤空間

發(fā)布時(shí)間:2020-06-18 20:35:34 來(lái)源:網(wǎng)絡(luò) 閱讀:1940 作者:vaynedu 欄目:編程語(yǔ)言

一、課前預(yù)習(xí)

寫本篇文章的目的很簡(jiǎn)單,防止采坑、防止采坑、防止采坑
我們?cè)陂_發(fā)程序的過(guò)程中,往往需要預(yù)分配磁盤空間,防止因磁盤空間不夠而引發(fā)程序異常問(wèn)題(已踩過(guò)坑), 現(xiàn)網(wǎng)查閱資料,有些預(yù)分配磁盤空間的方法不正確,在這里特別記錄一下, 除此之外,把正確的預(yù)分配的方法和大家分享一下,如果其他人有建議,歡迎拍磚狠砸

二、假:磁盤預(yù)分配---ftruncate

1. 使用lseek、ftruncate到一個(gè)固定位置生成的“空洞文件”是不會(huì)占據(jù)真正的磁盤空間的。

#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;
}

測(cè)試結(jié)果
Linux創(chuàng)造固定的文件大小-預(yù)分配磁盤空間

2. fseek fputs填充文件的最后一個(gè)字節(jié)

#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

測(cè)試結(jié)果
Linux創(chuàng)造固定的文件大小-預(yù)分配磁盤空間

4. 額外補(bǔ)充:

1 .ls顯示文件的“邏輯上”的size, 這不是文件真正占用磁盤空間大小,這部分空間也會(huì)被其他進(jìn)程使用。
2 .du顯示文件“物理上”的size,即du顯示的size是文件在硬盤上占據(jù)了多少個(gè)block計(jì)算出來(lái)的

三、真:磁盤預(yù)分配---fallocate

1. 使用fallocate 或者posix_fallocate函數(shù)

請(qǐng)求tlinux內(nèi)核大神后,原來(lái)還存在fallocate 和 posix_fallocate這樣的函數(shù), 還是自己太low, 其實(shí)fallocate 和 posix_fallocate兩個(gè)最大的區(qū)別:

This is a nonportable, Linux-specific system call

廢話也不多說(shuō), 還是直接上代碼比較好一點(diǎn), 一目了然

#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;
}

測(cè)試結(jié)果:

root@xxx.xxx.xxx.xxx:/data6#time ./posix_fallocate 
fallocate create 10.00G file

real    0m0.014s
user    0m0.000s
sys 0m0.014s
root@xxx.xxx.xxx.xxx:/data6#ll -h posix_fallocate.file.txt 
-rw-r--r-- 1 root root 10G Oct 25 15:45 posix_fallocate.file.txt
root@xxx.xxx.xxx.xxx:/data6#du -sh posix_fallocate.file.txt 
11G posix_fallocate.file.txt

Linux創(chuàng)造固定的文件大小-預(yù)分配磁盤空間
不僅可以占住空間,而且速度非常快, 之前有過(guò)一個(gè)愚蠢的想法, 用dd命令直接創(chuàng)建10G文件,但是會(huì)造成IO毛刺,肯定不能這么玩,要是創(chuàng)造100G文件豈不是涼涼了。dd命令還是安安靜靜壓測(cè)下磁盤性能或者創(chuàng)造一些小文件比較好。

2. 額外補(bǔ)充

  1. 磁盤空間預(yù)分配,不是所有l(wèi)inux系統(tǒng)都支持,有時(shí)候就分配失敗,這就沒(méi)有辦法了。如下
    ret = -1, errno = 95,  Operation not supported
  2. linux命令磁盤預(yù)分配---fallocate
    root@xxx.xxx.xxx.xxx:/data6#fallocate -l 10G  2.txt
    root@xxx.xxx.xxx.xxx:/data6#ll -h 2.txt   
    -rw-r--r-- 1 root root 10G Oct 25 15:33 2.txt
    root@xxx.xxx.xxx.xxx:/data6#du -sh 2.txt 
    11G 2.txt
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI