Getting started with golang seek
The previous article discussed how to work with files in Golang. With the os package, we can easily open, read, write and get the metadata,... In today's post, I will show you some examples of working with os.Seek()
function in Golang:
os package:
Package os provides a platform-independent interface to operating system functionality. The design is Unix-like, although the error handling is Go-like; failing calls return values of type error rather than error numbers. Often, more information is available within the error. For example, if a call that takes a file name fails, such as Open or Stat, the error will include the failing file name when printed and will be of type *PathError, which may be unpacked for more information.
func (f *File) Seek(offset int64, whence int) (ret int64, err error)
: 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.
Note that: Golang seek from has three constant values as follows:
SeekStart
= 0: the file's starting point is used.SeekCurrent
= 1: the seek is made in relation to the file's most recent offset.SeekEnd
= 2: it searches in relation to the file's end.
Example 1: Simple usage of Seek() function
Will read a file and use Seek()
function to set the offset for the next Read in the below example:
package main
// Importing fmt, io, and strings
import (
"fmt"
"os"
)
func main() {
// read the file
data, err := os.ReadFile("./data.txt")
checkErr(err)
fmt.Println("File content: ", string(data))
file, err := os.Open("./data.txt")
checkErr(err)
// read data to a byte slice
byteSlice1 := make([]byte, 4)
content1, err := file.Read(byteSlice1)
checkErr(err)
fmt.Printf("Read %d bytes with the content: %s", content1, string(byteSlice1[:content1]))
// set the offset
_, err = file.Seek(4, 0)
checkErr(err)
// read data at the offset
byteSlice2 := make([]byte, 7)
content2, err := file.Read(byteSlice2)
checkErr(err)
fmt.Println("")
fmt.Printf("Read %d bytes with the content: %s", content2, string(byteSlice2[:content2]))
fmt.Println("")
}
// print if error
func checkErr(e error) {
if e != nil {
panic(e)
}
}
Output:
File content: This is an example file. Hello GoLinuxCloud members!
Read 4 bytes with the content: This
Read 7 bytes with the content: is an
Example 2: Using constant in Seek() function
Here is an example of using constants SeekCurrent
and SeekEnd
:
package main
// Importing fmt, io, and strings
import (
"fmt"
"io"
"os"
)
func main() {
// read the file
data, err := os.ReadFile("./data.txt")
checkErr(err)
fmt.Println("File content: ", string(data))
file, err := os.Open("./data.txt")
checkErr(err)
// read data to a byte slice
byteSlice1 := make([]byte, 4)
content1, err := file.Read(byteSlice1)
checkErr(err)
fmt.Printf("Read %d bytes with the content: %s", content1, string(byteSlice1[:content1]))
// set the SeekCurrent=1
_, err = file.Seek(4, io.SeekCurrent)
checkErr(err)
// read data at the offset
byteSlice2 := make([]byte, 7)
content2, err := file.Read(byteSlice2)
checkErr(err)
fmt.Println("")
fmt.Printf("Read %d bytes with the content: %s", content2, string(byteSlice2[:content2]))
fmt.Println("")
// offset from the end
_, err = file.Seek(-5, io.SeekEnd)
checkErr(err)
// read data at the offset
byteSlice3 := make([]byte, 5)
content3, err := file.Read(byteSlice3)
checkErr(err)
fmt.Printf("Read %d bytes with the content: %s", content3, string(byteSlice3[:content3]))
fmt.Println("")
}
// print if error
func checkErr(e error) {
if e != nil {
panic(e)
}
}
Output:
File content: This is an example file. Hello GoLinuxCloud members!
Read 4 bytes with the content: This
Read 7 bytes with the content: an exam
Read 5 bytes with the content: bers!
Summary
In today's post, I have given 2 examples of using Seek()
function to shift offset for the next read file in Golang. With the detailed examples above, you can write your own read functions with a flexible offset for your reader.
References
https://pkg.go.dev/os#File.Seek
https://en.wikipedia.org/wiki/Offset_(computer_science)