標準ライブラリのコードリーディングを始めた。
開発環境
> docker-compose exec app go version
go version go1.16.3 linux/amd64
> docker --version
Docker version 19.03.12, build 48a66213fe
> docker-compose --version
docker-compose version 1.27.2, build 18f557f9
Seek
// Seek sets the offset for the next Read or Write on file to offset, interpreted
// according to whence: 0 means relative to the origin of the file, 1 means
// relative to the current offset, and 2 means relative to the end.
// It returns the new offset and an error, if any.
// The behavior of Seek on a file opened with O_APPEND is not specified.
//
// If f is a directory, the behavior of Seek varies by operating
// system; you can seek to the beginning of the directory on Unix-like
// operating systems, but not on Windows.
func (f *File) Seek(offset int64, whence int) (ret int64, err error) {
if err := f.checkValid("seek"); err != nil {
return 0, err
}
r, e := f.seek(offset, whence)
if e == nil && f.dirinfo != nil && r != 0 {
e = syscall.EISDIR
}
if e != nil {
return 0, f.wrapErr("seek", e)
}
return r, nil
}
ドキュメント部分を翻訳すると、
Seekは、ファイルに対する次の Read または Write の offset を、whence に従って解釈される offset に設定します。0 はファイルの原点からの相対位置、1 は現在の offset からの相対位置、2 は終端からの相対位置を意味します。
- offset: 配列やデータ構造オブジェクト内の、先頭から所定の要素まで距離を示す整数
- whence: どこから
whence を 3パターン から設定できる。
定数名 (実際の値) | whence の基準 |
---|---|
SeekStart (0) | 先頭 |
SeekCurrent (1) | 現在の offset |
SeekEnd (2) | 終端 |
Seek はファイルを指定した位置から読ませることが得意そう。
コードを書いてみる。
コード
テキストファイルの読み出し位置をコントロールして好きな位置で取り出せるようにする。
> cat test.txt
Hello, World!
package main
import (
"fmt"
"io"
"io/ioutil"
"log"
"os"
)
func main() {
f, err := os.Open("./test.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
f.Seek(0, io.SeekStart)
bytes, err := ioutil.ReadAll(f)
if err != nil {
log.Fatal()
}
fmt.Println("length:", len(bytes))
fmt.Println(string(bytes))
}
↓
> docker-compose exec app go run main.go
length: 13
Hello, World!
f.Seek(0, io.SeekStart)
ここで、offset を先頭を基準として 0 に設定している。
そのため読み出したテキストは全文表示される。(Hello, World!
)
f.Seek(5, io.SeekStart)
↓
> docker-compose exec app go run main.go
length: 8
, World!
offset を先頭を基準として 5 に設定している。(= 先頭から 5 進めた箇所から読み込む)
f.Seek(0, io.SeekCurrent)
↓
> docker-compose exec app go run main.go
length: 13
Hello, World!
offset を現在の offset を基準として 0 に設定している。(= offsetを変更していないので、先頭から読み込む)
f.Seek(-5, io.SeekEnd)
↓
> docker-compose exec app go run main.go
length: 5
orld!
offset を終端を基準として -5 に設定している。(= 終端から 5 戻した箇所から読み込む)