モジュールのレッスン (3/5)
`io` と `os`: ファイルとストリーム
Go でのファイルとストリームの読み取りと書き込みは、os (開く、作成、メタデータ、プロセス) と io (バイト ソースを抽象化する Reader/Writer インターフェイス) という 2 つの補完的なパッケージを中心に展開します。
ファイルの読み取りと書き込み: ショートカット
小さいファイルや構成ファイルの場合は、1 回の呼び出しで十分です。
data, err := os.ReadFile("input.txt") // returns []byte
if err != nil {
return err
}
fmt.Println(string(data))
err = os.WriteFile("out.txt", []byte("ciao"), 0644)os.ReadFile が開き、すべてをメモリに読み取って閉じます。数 MB までは完璧です。それ以上に、ストリーミングの方が優れています。
ストリーミング用にファイルを開く
大きなファイルまたは増分アクセスの場合は、ファイルを開いて defer を使用して閉じます。
f, err := os.Open("big.txt") // read-only
if err != nil {
return err
}
defer f.Close()
buf := make([]byte, 4096)
for {
n, err := f.Read(buf)
if n > 0 {
process(buf[:n])
}
if err == io.EOF {
break
}
if err != nil {
return err
}
}os.Open は読み取り専用で開きます。書き込むには、os.Create (存在する場合は切り捨てられます) または os.O_APPEND | os.O_CREATE | os.O_WRONLY のようなフラグを付けた os.OpenFile(path, flag, perm) を使用します。
io.Reader および io.Writer: ユニバーサル インターフェイス
type Reader interface { Read(p []byte) (n int, err error) }
type Writer interface { Write(p []byte) (n int, err error) }標準ライブラリが io.Reader を受け入れる場合はどこでも、ファイル (*os.File)、文字列 (strings.NewReader)、*bytes.Buffer、HTTP 応答 (resp.Body)、解凍器を渡すことができます。io.Writer についても同様です。
// Copy from a Reader to a Writer (e.g. download → file).
n, err := io.Copy(dst, src)io.Copy はバイト パイプラインの主力製品であり、バッファリングと EOF を正しく処理します。 io.ReadAll(r) は、EOF までのすべてを []byte に読み取ります。
os.Args: CLI 引数
os.Args は文字列のスライスです。インデックス 0 はプログラム名で、実引数の 1 から始まります。
func main() {
if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, "uso: prog <nome>")
os.Exit(1)
}
fmt.Println("ciao", os.Args[1])
}より構造化された解析 (フラグ、デフォルト、ヘルプ) を行うには、stdlib の flag パッケージ、または cobra などの外部ライブラリを使用します。
os.Stdin、os.Stdout、os.Stderr
これらは 3 つのグローバル *os.File です。io.Reader または io.Writer が受け入れられる場合はどこでも、それらを渡すことができます。
fmt.Fprintln(os.Stderr, "log diagnostico")
io.Copy(os.Stdout, os.Stdin) // echo演習
最初のコマンドライン引数 (os.Args[1]) を出力します。見つからない場合は、「manca argomento」を印刷して戻ります。
3 回の試行後に解決策が利用可能になります
os.WriteFile (権限 0644) を使用して、文字列「ciao」をファイル「out.txt」に書き込みます。エラーを処理します。
3 回の試行後に解決策が利用可能になります
os.Args のプログラム名のインデックスは何ですか?
fmt.Println(os.Args[???])