Ce face os.File.Seek
Fiecare fișier deschis are o poziție curentă; Read și Write pornesc de acolo. Seek o mută la offset octeți față de un punct de referință: io.SeekStart (începutul), io.SeekCurrent (poziția actuală) sau io.SeekEnd (finalul).
Returnează noua poziție, măsurată de la început. Trucul f.Seek(0, io.SeekCurrent) afli poziția fără s-o schimbi, iar f.Seek(0, io.SeekEnd) returnează dimensiunea fișierului. Pe un fișier deschis cu O_APPEND, scrierea merge oricum la final.
Parametri
| Parametru | Descriere |
|---|---|
offset |
Câți octeți să se deplaseze; poate fi negativ față de io.SeekCurrent sau io.SeekEnd. |
whence |
Punctul de referință: io.SeekStart, io.SeekCurrent, io.SeekEnd. |
Ce returnează
Noua poziție (de la începutul fișierului) și nil, sau o eroare.
Exemple
Exemplul 1: Citire de la o poziție anume
package main
import (
"fmt"
"io"
"os"
)
func main() {
os.WriteFile("alfabet.txt", []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0o644)
f, _ := os.Open("alfabet.txt")
defer f.Close()
buf := make([]byte, 3)
poz, _ := f.Seek(10, io.SeekStart)
f.Read(buf)
fmt.Printf("de la %d: %s\n", poz, buf)
poz, _ = f.Seek(-3, io.SeekEnd)
f.Read(buf)
fmt.Printf("de la %d: %s\n", poz, buf)
dim, _ := f.Seek(0, io.SeekEnd)
fmt.Println("dimensiune:", dim)
}
Rezultat
de la 10: KLM
de la 23: XYZ
dimensiune: 26
Exemplul 2: Recitirea de la început
După io.ReadAll poziția este la final; fără Seek, a doua citire ar fi goală.
package main
import (
"fmt"
"io"
"os"
)
func main() {
os.WriteFile("lista.txt", []byte("mere, pere, prune"), 0o644)
f, _ := os.Open("lista.txt")
defer f.Close()
prima, _ := io.ReadAll(f)
adoua, _ := io.ReadAll(f)
fmt.Printf("prima: %q | a doua: %q\n", prima, adoua)
f.Seek(0, io.SeekStart)
atreia, _ := io.ReadAll(f)
fmt.Printf("după Seek: %q\n", atreia)
}
Rezultat
prima: "mere, pere, prune" | a doua: ""
după Seek: "mere, pere, prune"
Exemplul 3: Modificarea unui octet în loc
package main
import (
"fmt"
"io"
"os"
)
func main() {
os.WriteFile("cod.txt", []byte("PRODUS-A-2025"), 0o644)
f, _ := os.OpenFile("cod.txt", os.O_RDWR, 0)
f.Seek(7, io.SeekStart)
f.Write([]byte("B"))
f.Close()
date, _ := os.ReadFile("cod.txt")
fmt.Println(string(date))
}
Rezultat
PRODUS-B-2025
Greșeli frecvente
- Citești de două ori același fișier și a doua oară nu primești nimic. Poziția a rămas la final; apelează
Seek(0, io.SeekStart). - Folosești
Seekpeos.Stdinsau pe un pipe. Acestea nu permit deplasarea și dau eroare.
Comenzi înrudite
os.File.Read: Citește din fișier cel mult len(b) octeți în slice-ul b și returnează câți a citit.os.Truncate: Schimbă dimensiunea unui fișier: taie ce depășește sau completează cu octeți zero.os.File: Tipul care reprezintă un fișier deschis; îl obții cu os.Open, os.Create sau os.OpenFile.io.ReadAll: Citește tot ce oferă un Reader, până la final, și returnează datele ca slice de octeți.