kurumi-bioの雑記帳

プログラミング、パソコン、ペット、 犬、お出かけ

初心者のGo言語 -23- <NewSyscallError,Pipe,ReadFile,Readlink>

こんにちは、kurumi-bioです。

第9回目の**osパッケージ(標準ライブラリー)**の学習です。

環境

  • Windows
    OSバージョン:Windows11 Home 22H2
    Go言語のバージョン:go version go1.20 windows/amd64
  • Linux
    OSバージョン:openSUSE Leap 15.4
    Go言語のバージョン:go version go1.20.1 linux/amd64

NewSyscallError関数

func NewSyscallError(syscall string, err error) error

関数の説明 NewSyscallError は、指定されたシステム コール名とエラーの詳細を含む新しい SyscallError をエラーとして返します。便宜上、err が nilの場合、NewSyscallError は nil を返します。

 

◆テストコード

package main

import (
	"errors"
	"fmt"
	"os"
)

func main() {
	e := os.NewSyscallError("Syscall", errors.New("Error"))
	fmt.Fprintf(os.Stderr, "%v\n", e)
}    
コードの説明 引数は、システムコール名とエラー詳細ですので、素直に"Syscall"と"Error"を渡して結果を確認します。

 

◆実行結果(Windows)

実行結果の説明 引数に渡した"Syscall"とErrorの間に":"が追加されました。
Go言語の流儀だと思いますので、システムコールでエラーメッセージを表示するときはos.NewSyscallErrorを使うようにしたいと思います。

Pipe関数

func Pipe() (r *File, w *File, err error)

関数の説明 パイプは、接続されたファイルのペアを返します。 r から読み取り、w に書き込まれたバイトを返します。ファイルとエラーがあればそれを返します。

 

◆テストコード

package main

import (
	"fmt"
	"os"
)

func main() {
	var s string
	r, w, _ := os.Pipe()

	fmt.Fprint(w, "aaa")
	w.Close()

	fmt.Fscan(r, &s)
	fmt.Printf("%s\n", s)
}    
コードの説明 wに"aaa"を書き込んで、rから読み取った情報を出力するプログラムです

 

◆実行結果(Windows)

実行結果の説明 変数rを読み込んで表示すると、変数wに書き込んだ値"aaa"が表示されました。

**広告の下に続きます。**

ReadFile関数

func ReadFile(name string) ([]byte, error)

関数の説明 ReadFile は、指定されたファイルを読み取り、内容を返します。呼び出しが成功すると、err == EOF ではなく、err == nil が返されます。 ReadFile はファイル全体を読み取るため、Read からの EOF を報告するエラーとして扱いません。

 

◆テストコード

package main

import (
	"fmt"
	"os"
)

func read(fileName string) {
	b, e := os.ReadFile(fileName)
	if e != nil {
		fmt.Fprintf(os.Stderr, "%v\n", os.NewSyscallError("os.ReadFile", e))
		return
	}
	fmt.Printf("%s\n", b)
}

func main() {
	read("test.txt")
	read("non.txt")
} 
ソースの説明 存在するファイルと存在しないファイルを指定した場合の動作を確認したかったので、 ファイル名を引数としたread関数を作成しました。
関数内でos.ReadFileを実行しています。
最初は存在するファイル(test.txt)を引数に渡して、次に存在しないファイル(non.txt)を引数に渡して、 動作を確認します。

 

◆実行結果(Windows)

実行結果の説明
  • "test.txt"を引数としてos.ReadFile関数を実行するとファイルの中身が出力されました。
  • 存在しないファイル"non.txt"を引数としてos.ReadFile関数を実行するとThe system cannot find the file specified(ファイルが見つからなかった)というエラーが発生しました。
エラーメッセージをos.NewSyscallError関数で作成していますので、メッセージの先頭に"os.ReadFile:"が出力されています。

ReadFile関数

func Readlink(name string) (string, error)

関数の説明 readlink は、指定されたシンボリック リンクの宛先を返します。エラーがある場合、タイプは *PathError になります。

 

◆テストコード

package main

import (
	"fmt"
	"os"
)

func rl(fileName string) {
	s, e := os.Readlink(fileName)
	if e != nil {
		fmt.Fprintf(os.Stderr, "%v [%t]\n", os.NewSyscallError("os.Readlink", e), os.IsNotExist(e))
		return
	}
	fmt.Printf("%s\n", s)
}

func main() {
	rl("symboliclink.txt")
	rl("hardlink.txt")
}    
ソースの説明 シンボリックリンクとハードリンクを引数に渡したときの結果を表示するプログラムです。今回も内部でos.Readlink関数を呼ぶ関数を作成しています。

 

◆実行結果(Windows)

実行結果の説明 シンボリックリンク(symboliclink.txt)はリンク先のファイル(test.txt)が表示されました。
ハードリンク(hardlink.txt)は、The file or directory is not a reparse point. (リパースポイント?ではない)というエラーが発生しました。

 

◆実行結果(Linux)

実行結果の説明 ハードリンクを引数にするとエラーになるのはWindowsと同じ挙動ですが、エラーメッセージがinvalid argument(無効な引数)というエラーメッセージになりました。Windowsのエラーメッセージよりわかりやすいかなと思いました。

**最後までご覧いただきありがとうございます**

先週のくるみ(2023.03.05)

こんにちは、kurumi-bioです。
2月26日(日)~3月4日(土)のくるみです。

犬を飼ってみて思うこと

いたずら
いつ頃からかハッキリと覚えていないのですが、おそらく1歳過ぎたくらいから目立った"いたずら"をしなくなったと思います。
元々悪さをしたくて"いたずら"をしているのではなく、"好奇心"とか"犬文化だと普通のこと"を飼い主が"いたずら"と感じてしまっているのかなと思ったりします。
ですので、ある程度の年齢になると落ち着いてきて"いたずら"の頻度が減るのかなと思います。

くるみは、「なんでも齧る」、「トイレシーツじゃない場所にトイレをする」が"2大いたずら"でした。

  • 家の壁紙を齧られたり、ゲージを齧られたり、ちょっと目を離したすきに口に入るものは齧ってみるという感じでした。 飲み込ませちゃダメなので、口に手を入れて取り出したり、落とした瞬間に取り上げたりしたのを覚えています。 一通り口に入れてどんな物かわかったのか、最近は小物が落ちてても口にすることは無くなりました。

  • シーツでトイレをすることを覚えたのですが、シーツ以外の場所ですることもあって、これには参りました。
    このままだと飼うのは厳しいと感じていたのですが、今ではトイレの時は庭に出るのでトイレシーツも使わなくなりました。

今は、留守の時も含め四六時中、家の中で自由にしていますが"いたずら"をしなくなりました。
家の中を自由に行動して、遊んで、寝て。それが普通に同じ生活空間でできてしまうそれが犬の不思議で良いところかなぁと思っています。

先週のくるみの様子

  • 散歩
    同じ公園に行ったのは3日でした。道順も変えたりして、長い時間散歩をすることが増えてきました。犬とは言え寒いのは苦手だったみたいです。
  • 朝ご飯
    今週も朝ご飯を食べなかったのは1日だけでした。いっぱい食べてよく寝て食欲もある。健康な証拠です。
  • 他人
    犬友達と会うことが増えてきて、他人が遠くにいれば気にしないで歩くようになってきました。明るくなってきたのも要因かもですが。

広告の下に続きます。

先週の写真


撮影日 2023年2月26日
ポカポカ陽気で気持ちよさそうに目を細めてます。


撮影日 2023年2月28日
外で昼寝をする日が増えてきました。


撮影日 2023年2月28日
ソファーの上で長い手足を器用に重ねています。手足が長細くてスタイル抜群です。


撮影日 2023年3月2日
5時前は、まだ暗いです。視線の先には野良猫がいたと思います。


撮影日 2023年3月3日
今日も小さな木の棒を見つけてガジガジしています。子供っぽい顔がかわいいです。


撮影日 2023年3月3日
「向こうにいるのは、犬友達かな。」


撮影日 2023年3月3日
「行こうかなぁ。どうしようかなぁ。」
優しい感じの横顔が、女の子だなぁ感じです。


撮影日 2023年3月4日
太陽が顔を出してオレンジ色のグラデーションが綺麗です。
写真を撮りたくて「待て!」で動きを止めたので、ちょっと嫌な顔をしてます。


撮影日 2023年3月4日
「お父さん、どうしたの?」
近くの木で鶯の声が聞こえたので、しばらく探した後に振り向いたら、不思議そうにこちらを見てました。春が近づいてます。


最後までご覧いただきありがとうございます

初心者のGo言語 -22- <Mkdir,MkdirAll,MkdirTemp>

こんにちは、kurumi-bioです。

第8回目のosパッケージ(標準ライブラリー)の学習です。

環境

  • Windows
    OSバージョン:Windows11 Home 22H2
    Go言語のバージョン:go version go1.20 windows/amd64
  • Linux
    OSバージョン:openSUSE Leap 15.4
    Go言語のバージョン:go version go1.20.1 linux/amd64

 

Mkdir関数

func Mkdir(name string, perm FileMode) error

関数の説明 mkdir は、指定された名前とパーミッション ビット (umask の前) を持つ新しいディレクトリを作成します。エラーがある場合、タイプは *PathError になります。

◆テストコード

package main

import (
    "fmt"
    "os"
)    
func main() {
    e := os.Mkdir("MkdirTest", 0750)
    if e != nil {
        fmt.Fprintf(os.Stderr, "Error: %v \n", e)
        os.Exit(1)
    }
    
}

カレントディレクトリに名前が"MkdirTest"でパーミッション0750(rwxr-x---)のフォルダを作成するプログラムです。

◆実行結果

"MkdirTest"フォルダが作成されました。

◆実行結果2

"MkdirTest"フォルダが存在するときに実行すると"フォルダ名: file exists"というエラーが発生します。

 

MkdirAll関数

func MkdirAll(path string, perm FileMode) error

関数の説明 MkdirAll は、path という名前のディレクトリと必要な親を作成し、nil を返すか、エラーを返します。許可ビット perm (umask の前) は、MkdirAll が作成するすべてのディレクトリに使用されます。 path が既にディレクトリである場合、MkdirAll は何もせず、nil を返します。

◆テストコード

package main
    
import (
    "fmt"
    "os"
)    
func main() {
    e := os.MkdirAll("MkdirAll/MkdirSub", 0750)
    if e != nil {
        fmt.Printf("err=%v\n", e)
    }
}

カレントディレクトリに名前が"MkdirAll"でパーミッション0750(rwxr-x---)のフォルダと、その直下に名前が"MkdirSub"でパーミッション0750(rwxr-x---)のフォルダを作成するプログラムです。

◆実行結果

"MkdirAll"フォルダと、その直下に"MkdirSub"フォルダが作成されました。

◆実行結果2

既に同名のフォルダが存在する状態で再度実行しましたがos.Mkdirと異なりエラーになりませんでした。

**広告の下に続きます。**

 

MkdirTemp関数

func MkdirTemp(dir, pattern string) (string, error)

関数の説明 MkdirTemp は、ディレクトリ dir に新しい一時ディレクトリを作成し、新しいディレクトリのパス名を返します。新しいディレクトリの名前は、パターンの末尾にランダムな文字列を追加することによって生成されます。 pattern に "*" が含まれている場合、代わりに最後の "*" がランダムな文字列に置き換えられます。 dir が空の文字列の場合、MkdirTemp は、TempDir によって返される一時ファイルの既定のディレクトリを使用します。 MkdirTemp を同時に呼び出す複数のプログラムまたはゴルーチンは、同じディレクトリを選択しません。不要になったディレクトリを削除するのは、呼び出し元の責任です。

◆テストコード

package main

import (
    "fmt"
    "os"
)         
func main() {
    d, e := os.MkdirTemp("", "temp")
    if e != nil {
        fmt.Fprintf(os.Stderr, "Error: %v \n", e)
        os.Exit(1)
    } else {
        fmt.Printf("Path=[%s]\n", d)
    }    
    d, e = os.MkdirTemp("", "te*mp")
    if e != nil {
        fmt.Fprintf(os.Stderr, "Error: %v \n", e)
        os.Exit(1)
    } else {
        fmt.Printf("Path=[%s]\n", d)
    }
}

一時ファイルの既定のディレクトリに"temp+ランダムな文字列"フォルダと"te+ランダムな文字列+mp"フォルダを作成するプログラムです。

◆実行結果(Windows)

Windowsの実行結果です。環境変数TEMPに指定しているパスの直下に一時ディレクトリが作成されました。

◆実行結果(Linux)

Linuxの実行結果です。環境変数にTEMPが無いので、一時ファイルの規定のディレクトリは、/tmpで固定だと思われます。ランダムな文字列は、毎回違う値になります。

**最後までご覧いただきありがとうございます**

初心者のGo言語 -21- <Link,LookupEnv>

こんにちは、kurumi-bioです。

第7回目のosパッケージ(標準ライブラリー)の学習です。

 

 

環境

  • Windows
    OSバージョン:Windows11 Home 22H2
    Go言語のバージョン:go version go1.20 windows/amd64
  • Linux
    OSバージョン:openSUSE Leap 15.4
    Go言語のバージョン:go version go1.20.1 linux/amd64

 

Link関数

func Link(oldname, newname string) error

Link は、oldname ファイルへのハード リンクとして newname を作成します。エラーが発生した場合、タイプは *LinkError になります。

[ソースコード]LinkSample.go

package main

import (
    "fmt"
    "os"
)
    
func main() {
    e := os.Link("src.txt", "dest.txt")
    if e != nil {
        fmt.Fprintf(os.Stderr, "Error: %v \n", e)
        os.Exit(1)
    }
} 

src.txtのハードリンクのdest.txtを作成します。

[実行結果]

Windowsの実行結果です。
fsutil hardlink list ファイル名で指定したファイルのハードリンクの一覧が表示されます。LinkSample.goを実行する前はsrc.txtのハードリンクは自ファイルのみでしたが、LinkSample.goを実行した後は、dest.txtがハードリンク先として表示されています。

 

Linuxの実行結果です。
lsコマンドにiオプションを指定してi-nodeを表示しています。src.txtとdest.txtが同じi-node番号(13781)になっていますのでハードリンクになっていることがわかります。またパーミッションの後の数字がハードリンクの数を表しており、2に変わっていることからもハードリンクが作成されたことがわかります。

 

既にdest.txtが作成されている場合は Cannot create a file when that file already exists. のエラーが発生します。

 

src.txtが存在しない場合は The system cannot find the file specified. のエラーが発生します。

LookupEnv関数

func LookupEnv(key string) (string, bool)

LookupEnv は、キーによって指定された環境変数の値を取得します。変数が環境に存在する場合、値 (空の場合もあります) が返され、ブール値は true になります。それ以外の場合、戻り値は空になり、ブール値は false になります。

[ソースコード]LookupEnvSample.go

package main

import (
    "fmt"
    "os"
)

func main() {
    s, b := os.LookupEnv("CPU")
    if b == true {
        fmt.Printf("CPU=[%s]\n", s)
    } else {
        fmt.Println("Not Found.")
    }
    
    s, b = os.LookupEnv("LANGUAGE")
    if b == true {
        fmt.Printf("LANGUAGE=[%s]\n", s)
    } else {
        fmt.Println("Not Found.")
    }
    
    s, b = os.LookupEnv("NON")
    if b == true {
        fmt.Printf("NON=[%s]\n", s)
    } else {
        fmt.Println("Not Found.")
    }
    
}


環境変数のCPU、LANGUAGE、NONを取得して表示します。環境変数が存在しなかった場合は"Not Found."と表示します。

[実行結果]

Linuxの実行結果です。
Windowsでは、値が空の環境変数を作れなかったため<Linuxで試しました。環境変数CPUの値は、x86_64で、環境変数LANGUAGEの値は空、環境変数NONは存在しませんでした。ブール値が戻ってくるので、環境変数が存在するが値が空という判断が可能になっています。

**最後までご覧いただきありがとうございます**

<商品紹介>パソコン用の工具紹介

こんにちは、kurumi-bioです。

普段使用している工具を紹介します。


帯電防止ブレスレット

帯電防止ESDリストストラップ | FEITA アース線2.4 mの帯電防止ブレスレットクリップ付きバーガンディ1個の帯電防止リストストラップ
です。

パソコン内部に触る時に、体から発生する静電気を逃がして、精密機器に影響を与えないようにするために使用します。

帯電防止リストストラップ

帯電防止リストストラップ(裏)

リストリングは、アジャスターで長さの調整が可能で最大で直径約5cm、円周約20cmです。伸縮性があるのできつい感じはしないです。
コードの長さは、約60cm~約1m80cmで、末端にクリップが付いています。また手首を通す方は、クルクルと自由に回るようになっています。 パソコンを作成している間ずーっと付けていましたが気にならないで作業できました。 付けていれば安心という程度ですが、数万するパソコンを壊すくらいなら安い買い物だと思っています。

プラスチックスクライブ

[BROWN PARKER] プラスチックスクライブ (ブルー+ブラック/各10本入り) 携帯電話修理ツール スパッジャー
です。

ノートパソコンのケースをこじ開けるときに使います。隙間に入れてつーっと一周するとケースが外れる感じです。 両端は、ヘラみたいな形と三角形を潰した形になっています。長さは約14.5cmで厚さは約1mm(持つところは約3mm)です。 青と黒が各10本で合計20本入っています。 ヘラの方を使いますが、三角形の方は使ったことが無いです。スマートフォンなどで使うのでしょうか。

プラスチックスクライブ

プラスチックスクライブ(使用後)

爪でこじ開けるよりも、スクライブを使った方がスムーズです。おそらく爪だと中まで入り切っていないからだと思います。 2回使うと写真のようにボロボロになりますので、使い捨てと考えた方が良いです。
20本入りで長く使えますし、パソコン本体と爪に傷が付かないので、使って損は無いと思いました。

ラチェットドライバー

アネックス(ANEX) ラチェットドライバー 差替式 ボールグリップ クイックボール72 No.397-D
です。

ラチェットドライバーです。ハンドル(持つ部分)とドライバーが独立して動きます。ハンドル中央部の赤いスイッチで正転・逆転・固定の切り替えができます。

ラチェットドライバー

本体の長さは約19.5cmで、ドライバー部分だけですと約10cmです。ハンドルの部分に切り替えスイッチがあります。 ドライバー部分は、両頭ビットで+2と-6です。ドライバーの長さは13.5cmです。ギア枚数72枚で、逆方向に回すと心地よくギリギリギリと音がしてドライバー(ネジ)が回らないです。 デスクトップパソコンを作る時に使いましたが、普通のドライバーと比べると腕を回さなくてよいので手の疲れが全然違います。ネジが緩んだら指先だけで回せます。 あえて難点をあげると、稀に気付かないで赤い切り替えスイッチに触って固定位置になって手がガックっとなってしまうことです。
一本持っておけば、ほとんどの家具に使えますので何かと重宝すると思います。

精密ドライバー

ベッセル(VESSEL) 精密 ドライバー Gグリップ +0×100 990
です。

+0の精密ドライバーです。ノートパソコンの内部パーツのネジで使用します。デスクトップパソコンを作成するときは、使わなかったです。

精密ドライバー
本体の長さは約20cmで、ドライバー部分だけだと約10.3cmです。ハンドル(持つ部分)の赤色部分が独立して回るようになっています。 赤い部分ですが銀色の玉が入っており、この玉が錘となって若干出っ張った方が必ず下になります。そうすると持った時に手の中にいい感じで収まります。 後は指先でハンドルの黒い部分をクリクリ回すとネジを回すことができます。ドライバーの基本の押しながら回すが気持ちよくできます。
精密ドライバーは100円ショップでも売っていますが、メーカー品を使った方が良いと感じさせる1本です。

ドライバー長さ比較

ラチェットドライバーと精密ドライバーは、ほぼ同じ長さです。このくらいが使いやすいと思います。

最後までご覧いただきありがとうございます

先週のくるみ(2023.02.26)

こんにちは、kurumi-bioです。
2月19日(日)~25日(土)のくるみです。

犬を飼ってみて思うこと

散歩
犬種や個体差にもよりますが、犬を飼うと毎日の散歩を欠かすことができません。 くるみの場合は、朝晩の2回散歩します。トイレ、犬仲間との挨拶、パトロールと大事な時間です。 ですので、飼い主が散歩を負担と感じてしまうとお互い辛い思いをすることになります。

負担と感じるかどうかは、「体力」と「時間」そして「(自分が)散歩が好き」が関係するかなと思います。

(個体差によりますが)数時間歩くだけの「体力」が必要です。 また散歩中は、車等の危険物や好奇心をくすぐる物が無いか周りを見ながら歩くので気疲れもします。

散歩をする「時間」を確保する必要があります。時間が無くてセカセカ歩いて、匂いを嗅いでるのに引っ張ったりしてしまうと、 犬の好奇心を削いでしまい散歩をする意味が無くなってしまいます。

自分が「散歩が好き」ならば良い散歩相手になります。 今まで通ったことがない道を発見したり、季節の移り変わりを感じ取ったり、一緒に色々な体験ができます。 「梅の花がきれいだね」とか、「コガモがいるよ」と話しかけながら散歩ができるのは、犬だからこそだと思います。
こんな散歩ができると時間の経過を忘れてしまいます。
苦労も多いですが、それ以上の楽しみがあるのが、犬との散歩だと思っています。

先週のくるみの様子

  • 散歩
    朝の散歩は、同じ公園に7日間のうち6日行きました。定番の行き先になりました。散歩時間は1時間半くらいでした。 新たな道を発掘した日は2時間散歩しました。
  • 朝ご飯
    朝の散歩の前にご飯を食べなかったのは、7日間のうち1日だけでした。暖かくなって散歩時間が伸びて食欲が出てきたのだと思います。
  • 他人
    明るくなる時間が早くなるにつれて、少しずつ犬仲間に会う機会が増えました。徐々に慣れて(去年の夏程度まで)他人に近寄れるようになるのかな。

<広告の下に続きます。>

先週の写真


地面に顔をつけている くるみ
撮影日 2023年2月19日
地面に顔をこすりつけているように見えますが。


小さな棒を手で押さえてる くるみ
撮影日 2023年2月19日
小さな木の棒をガジガジしていました。大きな手でちょこんと押さえています。


顔に手を当てて眠そうな くるみ
撮影日 2023年2月19日
顔に手を当てて寝てます。


不機嫌な顔の くるみ
撮影日 2023年2月20日
女の子らしく菜の花を背景に撮りたかったのですが、これ以上近寄らなかったです。無理やりだったので、ちょっと不機嫌な顔してます。


竹林の くるみ
撮影日 2023年2月20日
竹林の中を歩くのは大好きです。「早く行こうよ」って顔をしています。


枝を齧る くるみ
撮影日 2023年2月20日
ものすごい顔です。枝を齧ってるだけなのですが。


枝を大きな手で押さえる くるみ
撮影日 2023年2月20日
大きな手で押さえてます。握手すると肉球が気持ち良いです。触れるのは飼い主の特権です。


朝焼けと くるみ
撮影日 2023年2月22日 5時50分
朝焼けで空がオレンジ色に染まり始めて綺麗です。くるみの表情がキリっとしていて、何気に首輪の光る色が朝焼けとシンクロしていて、かっこいいです。今週のお気に入りの一枚です。


一本道の くるみ
撮影日 2023年2月24日 6時5分
光る首輪が無くても認識できるくらい明るくなってきました。
畑の一本道ですが「この道は何処に続くのか」と雄大さと希望(不安?)を感じさせる一枚になりました。


最後までご覧いただきありがとうございます

初心者のGo言語 -20- <IsExist,IsNotExist,IsPathSeparator,IsPermission,IsTimeout,Lchown>

こんにちは、kurumi-bioです。 第6回目のosパッケージ(標準ライブラリー)の学習です。

環境

  • Windows
    OSバージョン:Windows11 Home 22H2
    Go言語のバージョン:go version go1.20 windows/amd64

  • Linux
    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に変更されました。

最後までご覧いただきありがとうございます