goの学習

Goの学習用のスクラップです。
よく使う処理をコメントとして残します。

標準出力の書き込みを削除する。
package main
import (
"fmt"
"strings"
"time"
)
func main() {
fmt.Print("書き込み中です")
time.Sleep(3 * time.Second)
fmt.Print("\r" + strings.Repeat(" ", 10) + "\r")
}

自動で消えるプログレスバー
package utils
import (
"fmt"
"strings"
)
type ProgressBar struct {
Total int
Count int
BarWidth int
}
func (pb *ProgressBar) Write() {
// 進捗率を計算
ratio := float64(pb.Count) / float64(pb.Total)
blocks := int(ratio * float64(pb.BarWidth))
// 棒グラフを作成
bar := fmt.Sprintf("\r[%s%s] %3.0f%%",
strings.Repeat("#", blocks),
strings.Repeat("-", pb.BarWidth-blocks),
ratio*100,
)
// 上書を表示
fmt.Print(bar)
}
func (pb *ProgressBar) Delete() {
fmt.Print("\r" + strings.Repeat(" ", pb.BarWidth+10) + "\r")
}
func main() {
// プログレスバーを初期化
progressbar := &utils.ProgressBar{Total: 100, Count: 0, BarWidth: 40}
for i := 0; i < 100; i++ {
time.Sleep(1 * time.Second)
progressbar.Count = i
progressbar.Write()
}
}

指定されたファイルをダウンロードする(例は画像ファイルのダウンロード用)
package utils
import (
"fmt"
"io"
"net/http"
"os"
)
func GetImg(imgURL string, path string, fileName string) {
// HTTP GETリクエストで画像データを取得
resp, err := http.Get(imgURL)
if err != nil {
panic(err)
}
defer resp.Body.Close()
// 保存用ファイルを作成
out, err := os.Create(fmt.Sprintf("%s/%d.jpg", path, fileName))
if err != nil {
panic(err)
}
defer out.Close()
// 画像データをファイルにコピー
_, err = io.Copy(out, resp.Body)
if err != nil {
panic(err)
}
}

ファイル・フォルダ関連

ファイルが存在するかのチェック
func fileExists(dir, filename string) bool {
path := filepath.Join(dir, filename)
info, err := os.Stat(path)
if err != nil {
return false // エラーがある = 存在しない(またはアクセス不可)
}
return !info.IsDir() // ディレクトリではなくファイルなら true
}

フォルダを作成する
-
os.Mkdir
:フォルダを作成する -
os.MkdirAll
: フォルダを再帰的に作成する
Mkdirは、指定された名前とパーミッション(umaskの前)で新しいディレクトリを作成する。ビット(umaskの前)。エラーが発生した場合、型は *PathError となる。
MkdirAll は path という名前のディレクトリを作成する、必要な親も一緒に作成し、nil を返す、またはエラーを返す。MkdirAll が作成するディレクトリには、perm (umask の前) というパーミッションビットが使用されます。MkdirAll が作成するすべてのディレクトリに使用される。
path がすでにディレクトリである場合、MkdirAll は何もしない。nil を返す。
フォルダ・ファイルの削除
-
os.Remove
: 指定されたファイルまたは空ディレクトリを削除する。 -
os.RemoveAll
: パスとパスの子ファイルや子ディレクトリを含めて削除する。
Remove は指定されたファイルまたはディレクトリを削除する。エラーが発生した場合は、*PathError型になります。
RemoveAll はパスと、それが含むすべての子を削除する。可能な限りすべてを削除しますが、最初に遭遇したエラーを返します。を返します。 パスが存在しない場合、RemoveAllはnil(エラーなし)を返します。エラーがある場合、それは [*PathError] 型になります。
import os
func main() {
os.Mkdir("path", "0755")
os.MkdirAll("path", "0755")
os.Remove("path")
os.RemoveAll("path")
}

ファイル・ディレクトリの名称変更
Renameはoldpathをnewpathにリネーム(移動)する。newpathがすでに存在し、ディレクトリでない場合、Renameはそれを置き換える。newpathがすでに存在し、ディレクトリである場合、Renameはエラーを返す。oldpathとnewpathが異なるディレクトリにある場合、OS固有の制限が適用されることがある。同じディレクトリ内であっても、Unix以外のプラットフォームでは、 Renameはアトミックな操作ではない。エラーが発生した場合、それは *LinkError 型である。
package main
import (
"fmt"
"os"
)
func main() {
err := os.Rename("aaa.txt", "bbb.txt")
if err != nil {
fmt.Printf("Error: %s\n", err)
}
}

ディレクトリ内の各ファイルを走査する
対象のディレクトリのツリー構造
aaa
├── 1111
├── 2222
├── 3333
└── bbbb
├── 1111
├── 2222
└── ccccc
├── 1111
└── 2222
プログラム実行後の出力
0: aaa
1: aaa/1111
2: aaa/2222
3: aaa/3333
4: aaa/bbbb
5: aaa/bbbb/1111
6: aaa/bbbb/2222
7: aaa/bbbb/ccccc
8: aaa/bbbb/ccccc/1111
9: aaa/bbbb/ccccc/2222
プログラム
package main
import (
"fmt"
"os"
"path/filepath"
)
func main() {
// func filepath.Walk(root string, fn filepath.WalkFunc) error
// type WalkFunc func(path string, info fs.FileInfo, err error) error
dirPath := "aaa"
var pathList []string
err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
// どんなエラーが発生する可能性がある?
// - 実行中に別のプロセスでファイルやディレクトリが削除された
// - 読み取り権限のないファイル等へのアクセス
// 権限のないファイルへのアクセス時にエラーが発生する
fmt.Println("エラー:", err)
return filepath.SkipDir
}
if info.IsDir() {
// ディレクトリです
}
pathList = append(pathList, path)
return nil
})
if err != nil {
fmt.Println("Walkエラー: %w", err)
} else {
for i, v := range pathList {
fmt.Printf("%00d: %s\n", i, v)
}
}
}
