こんにちは、kurumi-bioです。 第6回目のosパッケージ(標準ライブラリー)の学習です。
環境
Windows
OSバージョン:Windows11 Home 22H2
Go言語のバージョン:go version go1.20 windows/amd64Linux
OSバージョン:openSUSE Leap 15.4
Go言語のバージョン:go version go1.20.1 linux/amd64
IsExist関数
func IsExist(err error) bool
IsExist は、ファイルまたはディレクトリが既に存在することを報告するためにエラーが認識されているかどうかを示すブール値を返します。 ErrExist といくつかの syscall エラーによって満たされます。 この関数は、errors.Is よりも前から存在します。 os パッケージによって返されるエラーのみをサポートします。新しいコードでは、errors.Is(err, fs.ErrExist) を使用する必要があります。
<サンプルコード>IsExistSample.go
package main import ( "fmt" "os" ) func main() { e := os.Mkdir("isExistTest", 0750) if e != nil { fmt.Fprintf(os.Stderr, "os.Mkdir Error: %v\n", e) if os.IsExist(e) == true { fmt.Println("true") } else { fmt.Println("false") } } else { fmt.Println("success") } }
os.Mkdir
関数を使ってディレクトリを作成します。もし、エラーが発生した場合はエラー原因が既にディレクトリが存在するかの結果を返します。
<実行結果>
2回連続で実行すると、既に同名ディレクトリが存在するのでエラー(error)になります。
そのエラー(error)をos.IsExist(e)
の引数に渡すとtrue
が返ってきましたので、ディレクトリが存在しないためエラーになったことがわかりました。
IsNotExist関数
func IsNotExist(err error) bool
IsNotExist は、ファイルまたはディレクトリが存在しないことを報告するためにエラーが認識されているかどうかを示すブール値を返します。これは、ErrNotExist といくつかのシステムコール エラーによって満たされます。 この関数は、errors.Is よりも前から存在します。 os パッケージによって返されるエラーのみをサポートします。新しいコードでは、errors.Is(err, fs.ErrNotExist) を使用する必要があります。
<サンプルコード>IsNotExistSample.go
package main import ( "fmt" "os" ) func main() { e := os.Remove("isExistTest") if e != nil { fmt.Fprintf(os.Stderr, "Remove Error: %v\n", e) if os.IsNotExist(e) == true { fmt.Println("true") } else { fmt.Println("false") } } else { fmt.Println("success") } }
os.Remove
関数を使ってディレクトリを削除します。もし、エラーが発生した場合はエラー原因が対象ディレクトリが存在しないかの結果を返します。
<実行結果>
IsExistSample.goで作成したディレクトリを削除します。2回連続で実行すると1回目でディレクトリを削除するので2回目はエラーになります。
そのエラー(error)をos.IsNotExist
の引数に渡すとtrue
が返ってきましたので、ディレクトリが存在しないためエラーになったことがわかりました。
では、ディレクトリが存在する場合は、false
が返ってくるのか試してみます。
IsExistSample.goを実行しディレクトリを作成します。
作成したディレクトリにtest.txtというファイルを作成します。
IsNotExistSampleを実行すると、指定したディレクトリが空でなかったためos.Remove
がエラーを返します。
そのエラー(error)をos.IsNotExist
の引数に渡すとfalse
が返ってきましたので、ディレクトリが存在するのでエラーになったことがわかりました。
IsPathSeparator関数
func IsPathSeparator(c uint8) bool
IsPathSeparator は、c がディレクトリ区切り文字かどうかを報告します。
<サンプルコード>IsPathSeparatorSample.go
package main import ( "fmt" "os" ) func main() { b := os.IsPathSeparator('/') fmt.Print("/=") if b == true { fmt.Println("true") } else { fmt.Println("false") } fmt.Print("\\=") b = os.IsPathSeparator('\\') if b == true { fmt.Println("true") } else { fmt.Println("false") } fmt.Print(":=") b = os.IsPathSeparator(':') if b == true { fmt.Println("true") } else { fmt.Println("false") } }
/
と\
と:
が、ディレクトリ区切り文字かを返すプログラムです。
<実行結果>
上がWindowsで、下がLinuxの結果です。
Windowsでは/
と\
がセパレータとして使えますが、Linuxは/
のみセパレータとして使用可能です。
<広告の下に記事が続きます。>
IsPermission関数
func IsPermission(err error) bool
IsPermission は、アクセス許可が拒否されたことを報告するエラーが既知であるかどうかを示すブール値を返します。これは、ErrPermission といくつかの syscall エラーによって満たされます。 この関数は、errors.Is よりも前から存在します。 os パッケージによって返されるエラーのみをサポートします。新しいコードでは、errors.Is(err, fs.ErrPermission) を使用する必要があります。
<サンプルコード>IsPermissionSample.go
package main import ( "fmt" "os" ) func main() { _, e := os.ReadFile("test") if e != nil { fmt.Printf("err=%v\n",e) b := os.IsPermission(e) if b == true { fmt.Println("IsPermission: true") } else { fmt.Println("IsPermission: false") } if os.IsExist(e) == true { fmt.Println("IsExist: true") } else { fmt.Println("IsExist: false") } } }
os.ReadFile
関数を使ってファイルを読み込みます。もし、エラーが発生した場合はエラー原因がアクセス許可が拒否されたかを返します。
<実行結果>
Linuxで実行しました。Read権を落としていますのでos.ReadFile
がエラーを返します。
そのエラー(error)をos.IsPermission()
の引数に渡すとtrue
が返ってきましたので、アクセス許可が拒否されたのでエラーになったことがわかりました。
ファイルが存在するのにos.IsExist
関数がfalse
を返したのは不明です。
IsTimeout関数
func IsTimeout(err error) bool
IsTimeout は、タイムアウトが発生したことを報告するエラーが既知であるかどうかを示すブール値を返します。 この関数は errors.Is よりも前のものであり、エラーがタイムアウトを示しているかどうかの概念があいまいになる可能性があります。たとえば、Unix エラー EWOULDBLOCK は、タイムアウトを示す場合と示さない場合があります。新しいコードでは、os.ErrDeadlineExceeded など、エラーを返す呼び出しに適した値を持つ errors.Is を使用する必要があります。
<サンプルコード>IsTimeoutSample.go
package main import ( "fmt" "os" ) func main() { _, e := os.ReadFile("test") if e != nil { fmt.Printf("err=%v\n", e) b := os.IsTimeout(e) if b == true { fmt.Println("true") } else { fmt.Println("false") } } }
os.ReadFile
関数を使ってファイルを読み込みます。もし、エラーが発生した場合はエラー原因がタイムアウトが発生したかを返します。
<実行結果>
エラー原因がタイムアウトではなかったのでfalse
が返ってきました。
Lchown関数
func Lchown(name string, uid, gid int) error
Lchown は、指定されたファイルの数値 uid と gid を変更します。ファイルがシンボリック リンクの場合、リンク自体の uid と gid が変更されます。エラーがある場合、タイプは PathError になります。 Windows では、PathError でラップされた syscall.EWINDOWS エラーが常に返されます。
<サンプルコード>LchownSample.go
package main import ( "fmt" "os" ) func main() { e := os.Lchown("LchownTest", 1002, 1001) if e != nil { fmt.Fprintf(os.Stderr, "os.Lchown Error: %v \n", e) os.Exit(1) } else { fmt.Println("success") } }
LchownTestファイルのuidを1002、gidを1001に変更します。 予め1002のuidと1001のgidを作成しておく必要があります。
<実行結果>
上がWindowsで下がLinuxです。 Windowsは、サポートされていないためエラー終了しました。 Linuxは、指定したuidとgidに変更されました。
最後までご覧いただきありがとうございます