はじめに
Go1.23連載の6本目です。
Go1.23のos.CopyFS
の追加、path/filepath
パッケージの更新について解説します。
更新内容
os.CopyFS の追加
プロポーサルは#62484です。
io.fs/FS
をローカルにコピーできるようになりました。
バージョン1.22まではディレクトリのコピーなどは、filepath.Walk
などを使い再帰的にコピーを行うか、外部ライブラリなどを利用する必要がありました。
1.23では標準パッケージを利用しつつ簡単な実装でディレクトリコピーをできるようになりました。
package main |
os.CopyFS
の第2引数は io/fs.FS
のinterfaceに対応していれば良いので、標準パッケージではあれば go:embed
で埋め込んだファイルリストをコピー可能、is/fs.FSに準拠した外部ライブラリを利用すればS3やメモリ上にある仮想ファイルシステムをローカルにコピーすることも可能です。
embed
のos.CopyFS
利用のサンプルです。
package main |
io.fs/FS
は Open
しか用意されていないためio.fs/FS
=>ローカル方向へのコピーのみである点はご注意ください。
ちなみに後ほど紹介するLocalize
がos.CopyFS
の内部で利用されています。
(こちらで利用されているのはinternalパッケージですが)
Windowsおける os.Readlink と filepath.EvalSymlinks を(ほぼ)シンボリックリンクの評価のみに変更
プロポーサルは#63703です。
os.Readlink
の実装がドキュメントの記載である
Readlink returns the destination of the named symbolic link.
とは異なり、readlinkコマンドの挙動と一致させるような複雑な実装になっていました。
その結果深刻なバグ(#39786, #40176)が発生しおり、filepath.EvalSymlinks
も内部でos.Readlink
を利用しているため影響を受けていました。
今回の変更により以下のように変更されてます。
対象 | Before | After |
---|---|---|
os.Lstat | symlinksとmount pointsを両方考慮 | symlinksのみ考慮 |
os.Readlink | windows.GetFinalPathNameByHandle の結果からsymlinksとmount pointsを両方考慮 |
シンボリックリンクのターゲット ( IO_REPARSE_TAG_SYMLINK )を利用し返却 |
Window上でシンボリックを張り1.23rc2と1.22.5の違いを確認しましたが、単純なパターンでは結果は変わりませんでした。
確認ソースコード
シンボリックリンク準備コマンド
C:\gotest>type nul > ori.txt |
package main |
filepath.Localize の追加
プロポーサルは#57151です。
filepath.Localize
はスラッシュ区切りのパスをOSに合わせ安全に変換する機能です。
返却される値、エラーの有無はテストケース見ると分かりやすいです。
具体例をいくつか上げます。
入力値 | 返却値 (Windows) |
返却値 (UNIX) |
---|---|---|
a | a | a |
. | . | . |
a/b/c | a\b\c | a/b/c |
a/ | (error) | (error) |
a/./b | (error) | (error) |
a/.. | (error) | (error) |
a\b:c | (error) | a\b:c ( \ ,: を区切りとして扱わない) |
c: | (error) | c: |
/a | (error) | (error) |
.
(.
のみを除く)や..
が含まれていた場合、先頭末尾にスラッシュが入った場合にもエラーになるためかなり厳しくチェックすることが可能です。
まとめ
今回はos
, path/filepath
を中心に3件のアップデートを紹介しました。
os.CopyFS
はローカルに対するコピーの利便性向上、後半2つは安全性、安定性向上のアップデートでした。
明日は大江さんの keep-alive,Cookie です。