Goでcpみたいなものを作ってみました
この記事は初心者🌱の自分のためのメモに近いです。ご容赦を。
paizaで学習するときに、いちいちディレクトリを複製するのが手間だったのでディレクトリの複製がしたかった。
ちょうどGoでなんでもいいからツールを作ってみたかったから作った。
cpなんていう便利なものがあったことは知らなかった
主に使用したパッケージ
どれも標準パッケージですね
io
os
path/filepath
今回のリポジトリ
面白かったところ
os.Args
について
これを使用することによって、go run
以降の引数を取得できる。
go run . filename
だと os.Args
の要素の0番目が.
なのでファイルのパス。1番目がfilename
となる。
os.Args
の要素の1番目がある場合のみプログラムを続けたかったので、以下のように書いた。
if len(os.Args) == 2 {
directory_name = os.Args[1]
} else {
os.Exit(1)
}
os
パッケージまわりについて
os.Stat
は返り値にfs.FileInfo
とerror
を持つ。
fs.FileInfo
とはなんぞや。
type FileInfo interface {
Name() string // base name of the file
Size() int64 // length in bytes for regular files; system-dependent for others
Mode() FileMode // file mode bits
ModTime() time.Time // modification time
IsDir() bool // abbreviation for Mode().IsDir()
Sys() any // underlying data source (can return nil)
}
ということらしい。
ぱっと見で理解できそうなのは、Name
とSize
くらいかな...
と思ってたらIsDir
が目についた。
これ、ディレクトリかそうじゃないかboolで返してくれるじゃん。天才じゃん。
ってことで利用する。
os
パッケージにはディレクトリ作成の関数と、ファイル作成の関数が別で用意されているので、IsDir
を使って区別できた。
filepath.Walk()
について
func Walk(root string, fn WalkFunc) error
root
には探索したいディレクトリを入れる。
fn
のWalkFunc
ってなに。
type WalkFunc func(path string, info fs.FileInfo, err error) error
ってことらしい。
おそらく、 filepath.Walk()
君が、WalkFunc
君の引数にそれぞれのディレクトリ等のパスとかinfoを投げて、それらを利用した関数を書けるということだと思う。
実際に書いてみた。
func make_directory_or_file(filename string) {
var new_path string
filepath.Walk("original_directory", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
new_path = strings.Replace(path, "original_directory", filename, -1)
if info.IsDir() {
err := os.MkdirAll(new_path, 0755)
if err != nil {
log.Println(err)
os.Exit(1)
}
} else {
dst, err := os.Create(new_path)
if err != nil {
log.Println(err)
os.Exit(1)
}
src, err := os.Open(path)
if err != nil {
log.Println(err)
os.Exit(1)
}
_, err = io.Copy(dst, src)
if err != nil {
log.Println(err)
os.Exit(1)
}
}
return nil
})
}
これはさっきのos
パッケージも使って書いてみた。
わりかしコンパクトに書けたのではないかと思いたい。
ひとりごと
Walk
で思い出したけど、これはおそらくグラフ理論の木構造とか使ってんのかなぁみたいな。
静的解析ツールを学習する機会があったけどおそらく今回のWalk
と似たことをやっていたんだと思う。抽象構文木をつかって、要素を一つ一つに関数を実行してたんだね。今やっと理解できた。ってことで多少は理解が進んだから静的解析ツールの話も記事にまとめます。
今回の学習を先にしていればもっと理解が早かったのかあ…
感想
cpコマンドとほとんど同じことをやってるので便利なツールができた!みたいな感じにはならなかったけど得たものが凄い多かった。
こういう感じで簡単なものでもツールいっぱい作ってみようと思う。