こんにちは!
今日は、Go言語によるファイル操作を記事にしたいと思います。
<目次>
事前準備
以下のフォルダとファイルを任意の場所に作成してください。
1 2 |
mkdir file-handler touch file-handler/main.go |
現在パスの取得
File操作には、パスの取得が重要ですよね。
osモジュールのGetwd関数で取得しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package main import ( "fmt" "log" "os" ) func main() { root, err := os.Getwd() if err != nil { log.Fatal(err) } fmt.Println(root) } |
以下のコマンドを実行してみましょう。
1 2 3 4 5 |
pwd /home/hoge/tool/file-handler go run main.go /home/hoge/tool/file-handler |
main.goが格納されているパスが取得できてますね。
ディレクトリ走破
ファイル操作するにあたり、特定のディレクトリ内に格納されているファイル情報を全て取得したいってことはよくありますよね?
次はそのコードを書いてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package main import ( "fmt" "log" "os" "path/filepath" ) func getFileList(files *[]string) filepath.WalkFunc { return func(path string, info os.FileInfo, err error) error { if err != nil { fmt.Println(err) } *files = append(*files, path) return nil } } func main() { var files []string root, _ := os.Getwd() err := filepath.Walk(root, getFileList(&files)) if err != nil { log.Fatal(err) } else { fmt.Println(files) } } |
「path/filepath」モジュールのWalk関数を使いました。
第一引数にはrootのパスを、第二引数には「filepath.WalkFunc」typeの関数を渡します。
getFileList関数では、渡したrootパスを元にフォルダ検索をかけて、パスをfiles変数に格納してくれます。
実験のために、main.goファイルと同階層に次のファイルを作成しましょう。
1 2 3 4 5 |
touch sample1.txt touch sample2.txt touch sample3.txt touch sample4.txt touch sample5.txt |
それでは、コマンドを実行します。
1 2 3 4 |
go run main.go [/home/hoge/tool/file-handler /home/hoge/tool/file-hanxdler/main.go /home/hoge/tool/file-handler/sample1.txt /home/hoge/tool/file-handler/sample2.txt /home/hoge/tool/file-handler/sample3.txt /home/hoge/tool/file-handler/sample4.txt /home/hoge/tool/file-handler/sample5x .txt] |
素晴らしいですね。
ファイル圧縮
ファイル圧縮も簡単にできます。
先ほど作成したファイルをgz形式に圧縮しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
package main import ( "compress/gzip" "fmt" "io" "os" "path/filepath" "sync" ) func getFileList(files *[]string) filepath.WalkFunc { return func(path string, info os.FileInfo, err error) error { if err != nil { fmt.Println(err) } *files = append(*files, path) return nil } } // Directory判定 func isDir(path string) bool { fi, err := os.Stat(path) if err != nil { fmt.Println(err) return false } return fi.Mode().IsDir() } // ファイル圧縮 func compressFile(filename string, wg *sync.WaitGroup) { in, err := os.Open(filename) if err != nil { fmt.Println(err) } else { defer in.Close() out, err := os.Create(filename + ".gz") if err != nil { fmt.Println(err) } else { defer out.Close() gzout := gzip.NewWriter(out) _, err = io.Copy(gzout, in) gzout.Close() } } wg.Done() } func main() { var files []string root, _ := os.Getwd() err := filepath.Walk(root, getFileList(&files)) if err != nil { fmt.Println(err) } else { var wg sync.WaitGroup for _, file := range files { fmt.Println(file) if !isDir(file) { wg.Add(1) go compressFile(file, &wg) } } wg.Wait() fmt.Println("program OK!") } } |
今回は、ファイルの一つ一つをgzにしました。
非同期処理で、compressFile関数を実行してます。
sync.WaitGroupは、全ての非同期が処理を完了するまで、プログラムの停止を待ってくれる便利な機能です。
それでは、実行してみましょう。
1 |
go run main.go |
main.goファイルの配下にgzファイルが作成されるはずです。
おわりに
ここでは、よく使うファイル操作を書きましたが、まだまだ物足りませんねw
これからも便利なプログラムを見かけたり、書いたりしたらこの記事に追加していこうと思います!
コメントを残す
コメントを投稿するにはログインしてください。