ただし、実際に使用してみると、Go 言語のバイナリ形式での読み取りと書き込みは通常、カスタム形式よりもはるかに高速で、作成されるファイルのサイズもそれほど大きくないことがわかりました。ただし、gob.GobEncoder インターフェイスと gob.GobDecoder インターフェイスを満たすことで、一部の非 gob エンコード データを処理する必要がある場合、これらの利点が失われる可能性があります。
場合によっては、カスタム バイナリ形式を使用するソフトウェアを操作する必要がある場合があるため、バイナリ ファイルの扱い方を知っておくと非常に役立ちます。
カスタムバイナリを書き込む
Go 言語のエンコーディング/バイナリ パッケージの binary.Write() 関数を使用すると、バイナリ形式でのデータの書き込みが非常に簡単になります。関数のプロトタイプは次のとおりです。
func Write(w io.Writer, order ByteOrder, data interface{}) error
Write 関数は、パラメーター データのバイナリ エンコード形式をパラメーター w に書き込むことができます。パラメーター データは、固定長値、固定長値のスライス、または固定長値へのポインターである必要があります。パラメータの順序は、書き込まれるデータのバイト順序を指定します。構造体を書き込むとき、名前に_
が含まれるフィールドは 0 に設定されます。
簡単なサンプル プログラムを通じて Write 関数の使用法を示します。サンプル コードは次のとおりです。
package main
import (
"bytes"
"encoding/binary"
"fmt"
"os"
)
type Website struct {
Url int32
}
func main() {
file、err:= os.Create( "output.bin")
for i:= 1; i <= 10; i + + {
info:= Website {
int32(i),
}
if err!= nil {
fmt.Println( "ファイル作成に失敗しました "、err.Error())
return
}
defer file.Close()
var bin_buf bytes.Buffer
binary.Write(&bin_buf、binary.LittleEndian、info)
b:= bin_buf.Bytes()
、err = file.Write(b)
if err!= nil {
fmt.Println( "エンコードに失敗しました"、err.Error())
return
}
}
fmt.Println( "エンコード成功")
}
上記のプログラムを実行すると、現在のディレクトリに output.bin ファイルが生成されます。ファイルの内容は次のとおりです。
0100 0000 0200 0000 0300 0000 0400 0000
0500 0000 0600 0000 0700 0000 0800 0000
0900 0000 0a00 0000
カスタムバイナリを読み取る
カスタム バイナリ データの読み取りは、カスタム バイナリ データの書き込みと同じくらい簡単です。この種のデータを解析する必要はありません。データを書き込んだときと同じバイト順序を使用して、同じ型の値にデータを読み取るだけです。
サンプルコードは次のとおりです。
package main
import (
"bytes"
"encoding/binary"
"fmt"
"operatingSystem"
)
type Website struct {
Url int32
}
func main() {
file, err:= os.Open("output.bin")
defer file.Close()
if err!= nil {
fmt.Println("ファイルのオープンに失敗しました". err.Error())
return
}
m:= Website{}
for i:= 1; i <= 10; i ++ {
data:= readNextBytes(file、4)
buffer:= bytes.NewBuffer(data)
err = binary.Read(buffer、binary.LittleEndian、&m)
if err!= nil {
fmt.Println("バイナリファイルの読み取りに失敗しました", err)
return
}
fmt.Println("第"、i、"個の値:", m)
}
}
func readNextBytes(file * os.File、number int)[] byte {
bytes:= make([] byte、number)
、err:= file.Read(bytes)
if err!= nil {
fmt.Println("デコードに失敗しました", err)
}
return bytes
}
ここまでで、カスタム バイナリ データの読み取りおよび書き込み操作が完了しました。長さを表す整数表記とサイズを慎重に選択し、その長さの値を可変長値 (スライスなど) の内容の前に書き込む限り、バイナリ データの操作はそれほど難しくありません。
Go 言語によるバイナリ ファイルのサポートには、ランダム アクセスも含まれます。この場合、os.OpenFile() 関数を使用して (os.Open() ではなく) ファイルを開き、それに適切な許可フラグとモード (読み取り/書き込みの os.O_RDWR など) パラメータを渡す必要があります。
次に、os.File.Seek() メソッドを使用してファイルを検索し、読み書きしたり、os.File.ReadAt() メソッドと os.File.WriteAt() メソッドを使用して特定のバイト オフセットから読み取ることができます。データをフェッチまたは書き込みます。
Go 言語には、ファイル サイズ、権限、日付と時刻などの詳細情報を含む os.FileInfo を返す os.File.Stat() メソッドなど、その他の一般的に使用されるメソッドも用意されています。