Golang とスパース ファイル

上の青い「Flying Snow Ruthless」をクリックして公式アカウントをフォローし、スターを付けて、できるだけ早く記事を読んでください

オペレーティング システムには、非常に大きく見えても、実際にはほとんどディスク領域を占有しない特殊なファイルがあり、この種のファイルはスパース ファイルです。

この種のファイルの原理は、実際にはファイルの内容を空のバイト (0 ではなく NULL として理解できます) としてマークすることであり、空の内容は実際にはディスク領域を占有しないため、ホールパンチングとも呼ばれます。 、ちょうど紙(文書)に穴が開けられているのと同じで、これらの穴にはデータが保存されないため、スペースを占有しません。

スパースファイルを生成する

スパース ファイルの原理を理解すると、スパース ファイルを生成するのは簡単になります。以下では Go 言語を使用して 1GB のスパース ファイルを生成しますが、実際のディスク フットプリントは 0 です。

func main() {
   sparseFile, err := os.Create("sparse_file")
   if err != nil {
      log.Fatalln(err)
   }
   sparseFile.Truncate(1 << 30)
   sparseFile.Close()
}

このメソッドを使用して Truncate ファイルのサイズを設定し、終了を直接閉じると、スパース ファイルを取得できます。

➜  hello ls -ls sparse_file 
0 -rw-r--r-- 1073741824 Aug 22 22:19 sparse_file

ls -ls コマンドを使用すると 、このファイルの基本情報を確認できます。ここで、最初の数字は 0 ファイルが占有する実際のディスク容量 (0 バイト) を示していることに注意してください。 1073741824 ファイルのサイズを示します (1GB)。
そうですね、1GB のファイルは実際には 0 バイトしか占有しません。

コマンドに加えて 、 実際の占有サイズを表示するコマンドもls -ls あります 。du

➜  hello du sparse_file 
0       sparse_file

スパースファイルに数バイトを書き込む

すでにいくつかのバイトが書き込まれているスパース ファイルを作成することもできます。この用途では、ホールの内容については、 Seek スキップするメソッドを使用します。

func main() {
   sparseFile, err := os.Create("sparse_file")
   if err != nil {
      log.Fatalln(err)
   }
   sparseFile.Truncate(1 << 30)
   sparseFile.Write([]byte{0x01})
   sparseFile.Seek(1<<30-1, 0)
   sparseFile.Write([]byte{0x02})
   sparseFile.Close()
}

上記のコードでも 1GB のスパース ファイルが作成されますが、最初のバイトと最後のバイトのみが書き込まれます。 Seek これは良い方法で、飛び回ったり、特定の場所に書きたいものを書き込んだり、スパース ファイルの特性を維持したりすることができます。

スパース ファイルをサポートするシステムはどれですか

実際、現在私たちが使用しているほとんどのファイル システムはスパース ファイルをサポートしており、Windows NTFS、Linux Ext4、MacOS APFS などはすべてスパース ファイルをサポートしています。

ここで、2016 年に Apple が発表した APFS ファイル システムは、お使いのコンピュータが初期の Apple コンピュータである場合にはサポートされない可能性があることに注意してください。

Unix 風のシステムを例にとると、Go 言語を使用しなくても、次のようなスパース ファイルを簡単に作成できます。

➜  dd of=sparse-file bs=1k seek=5120 count=0

上記では 5M のファイルが作成されますが、実際のディスク容量は 0 です。

スパースファイルの応用

スパース ファイルの特性を理解すると、スパース ファイルの使用シナリオをいくつか考えることができるようになります。

そうです、将来的には大きくなるであろうファイルですが、現時点ではそれほど大きくありません。このようなシナリオには、スパース ファイルが最適であり、ディスクよりも大きなスパース ファイルを作成することもできます。

仮想マシンでは非常に一般的なディスク ミラーリングなど。サイズが 500G のディスクを作成したいと考えていますが、それほど多くのスペースを占有する必要はなく、必要なだけ使用できるため、スパース ファイルをディスク イメージとして使用するのに特に適しています。

たとえば、仮想マシンでよく使用されるメモリ スナップショットです。10 GB のメモリを備えた仮想マシンの場合、メモリ データのスナップショットを取得したいのですが、メモリ内のデータは固定されておらず、最大値は 10 GB のみです。

このとき、10 GB のスパース ファイルを作成し、仮想マシンのメモリ データをこのスパース ファイルに書き込むことができます。データを書き込むときは、ゼロ バイト以外のデータのみを書き込むことで、ディスクの使用量を削減できます。

ここでの Golang との組み合わせは syscall.Mmap システム コールを参照できます。自分で試すことができます。ここではこれ以上の例は示しません。

func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error)

まとめ

スパース ファイルは多くの特定のシナリオで適切に機能しますが、完璧ではありません。たとえば、ファイルを書き換えるとディスクが「突然」いっぱいになる場合があり、コピー、パッケージ化、またはリモート送信すると、スパース ファイルの特性が失われることがあります。

ただし、いずれの場合でも、これは特にディスク ミラーリング、スナップショット、ログなどのシナリオでは非常に優れたファイル特異性であり、これらを使いこなすことができれば、予期せぬメリットが得られるでしょう。

f06bcc2265efe8391fa858dbdc9ed85b.png

コードをスキャンしてフォローしてください

シェア、いいね、視聴が最大のサポートです

おすすめ

転載: blog.csdn.net/flysnow_org/article/details/126552675