ちょっとしたツールを作るのにも, DBを使うのが面倒な時にもファイル操作は便利.
サンプルコードの実行にはosパッケージをインポートしてください.
(Printしてるものには当然fmtも)
import (
"os"
"path/filepath"
)
ディレクトリを作る
if err := os.Mkdir("foo", 0777); err != nil {
panic(err)
}
サブディレクトリも作る
サブディレクトリもまとめて作りたい時
if err := os.MkdirAll("hoge/fuga", 0777); err != nil {
panic(err)
}
ファイル・ディレクトリの名前変更
fooをbarに変更
if err := os.Rename("foo", "bar"); err != nil {
panic(err)
}
ファイル・ディレクトリの移動
fooの下のtest.txtをbarへ移動.こちらもRenameを使う(どうなんだろう,これ)
if err := os.Rename("foo/test.txt", "bar/test.txt"); err != nil {
panic(err)
}
ファイル・ディレクトリの権限変更
コマンドのchmodと変わらないですね.
if err := os.Chmod("foo", 0666); err != nil {
panic(err)
}
ファイル・ディレクトリの削除
下記では中身のあるディレクトリは消せません(rmdirと同じですね)
if err := os.Remove("foo"); err != nil {
panic(err)
}
ファイル・ディレクトリの削除(中のファイルごと)
これで中身があろうと消せます.
if err := os.RemoveAll("foo"); err != nil {
panic(err)
}
ファイル・ディレクトリの存在確認
statでエラーが無いかで判断するのが良いようです.
_, err := os.Stat("foo.txt")
if err == nil {
fmt.Println("あった")
} else {
fmt.Println("なかった")
}
もうちょっと複雑な操作
ここから先はfilepathもインポートしてください.
(Printしてるものには当然fmtも)
import (
"os"
"path/filepath"
)
指定ディレクトリ下のファイル・ディレクトリ一覧の取得
filepath.Walkを使います.
これはちょっとややこしいので全部書きます.
walk_funcは匿名関数の方がわかりやすい場合もあるかもしれません.
package main
import (
"fmt"
"os"
"path/filepath"
)
func walk_func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
if path == "hoge/foo" {
return filepath.SkipDir
}
}
fmt.Println(path)
return nil
}
func main() {
root_dir := "."
err := filepath.Walk(root_dir, walk_func)
if err != nil {
panic(err)
}
}
実行結果
ディレクトリが荒れててちょっとわかりづらいですが.
twinbird@:~/go/src/file_operate$ ./file_operate
.
bar
bar/test.txt
blog.txt
file_operate
foo
hoge
sample.go
twinbird@:~/go/src/file_operate$ tree .
.
├── bar
│ └── test.txt
├── blog.txt
├── file_operate
├── foo
├── hoge
│ └── foo
│ └── test2.txt
└── sample.go
ちょっと解説入れると
- filepath.Walkはディレクトリやファイルが見つかるたびにwalk_funcをコールバックで呼び出すことになります.
- コールバックのinfoにはファイル情報が入っているので参照できます.
- コールバックの戻り値にfilepath.SkipDirを使えば,走査中の配下のディレクトリは無視するようです.基本はnilを戻します.
ファイルパスの操作
ファイル操作するときにはファイルパスの操作もセットみたいなもんでしょう.
絶対パスを取得する
filepath.Absを使います.
abs_path, err := filepath.Abs(".")
if err != nil {
panic(err)
}
fmt.Println(abs_path)
実行結果
/home/twinbird/go/src/file_operate
ファイル名を取得する
base_path := filepath.Base(`C:\Users\IMAI\Desktop\test\a.txt`)
fmt.Println(base_path)
実行結果
a.txt
ファイルパスを連結する
base_path := `C:\Users\IMAI\Desktop\test`
file_path := "a.txt"
joined_path := filepath.Join(base_path, file_path)
fmt.Println(joined_path)
実行結果
C:\Users\IMAI\Desktop\test\a.txt
拡張子を取得する
file_path := "a.txt"
ext := filepath.Ext(file_path)
fmt.Println(ext)
実行結果
.txt