2

ファイル マッピングを使用して、私が取り組んできたいくつかの大きな配列を使用するプログラムのメモリ フットプリントを削減しています。これらの配列の目的のサイズがわからないため、配列が到達しないことがわかっているレベルまでサイ​​ズを過大評価し、ファイルを最終的なサイズに切り詰めて配列を完成させています。幸いなことに、マップされたファイルを作成するために使用しているコード (この投稿の下部) は、試したすべてのマシンでスパース ファイルを作成します。そうでない場合は、ディスク容量の問題が発生します。

質問は: スパース ファイルを作成することが保証されているマッピングの前に lseek を呼び出してファイルを拡張するか、または少なくとも合理的な Linux ディストリビューションと Solaris でそうすることに依存できますか。

また、数百 GB の非スパース ファイルを作成するよりも終了する方がよいため、作成されたファイルがスパースであることを確認する方法はありますか。

output_data_file_handle = open(output_file_name,O_RDWR | O_CREAT ,0600);
lseek(output_data_file_handle,output_file_size,SEEK_SET);
write(output_data_file_handle, "", 1);
void * ttv = mmap(0,(size_t)output_file_size,PROT_WRITE | PROT_READ, MAP_SHARED,output_data_file_handle,0);
4

2 に答える 2

4

2番目の質問を参照してください:ファイルが(部分的に)スパースファイルであるかどうかをテストするには、stat()コマンドを使用できます。

例:

#include <stdio.h>
#include <sys/stat.h>

...

struct stat st = {0};

int result = stat("filename", &st);
if (-1 == result)
  perror("stat()");
else
{
  printf("size/bytes: %ld", st.st_size); /* 'official' size in bytes */
  printf("block size/bytes: %ld", st.st_blksize);
  printf("blocks: %ld", st.st_blocks); /* number of blocks actually on disk */

  if (st.st_size > (st.st_blksize * st.st_blocks))  
       printf("file is (at least partially) a sparse file");
}

...
于 2012-12-17T12:08:08.133 に答える
4

マニュアルlseekでは、ファイルの末尾を超えてシークするときの動作が指定されていますが、スパース ファイルについては言及されていません。したがって、OS、特に使用されるファイルシステムに依存します。

システムでスパース ファイルを作成できるかどうかをテストするには、次のようにします。

dd if=/dev/zero of=/path/to/sparse.txt bs=1k seek=1024 count=1
du /path/to/sparse.txt

これは、1024 個の 1k ブロックをスキップしてから、1024 バイトを書き込みます。duスパース ファイルの場合は数 kB しか表示されず、そうでない場合は約 1.1 MB が表示されます。

于 2012-12-17T12:23:15.480 に答える