Alamat berkas kelihatan sederhana, tetapi sistem operasi tidak sepakat soal pemisah: Linux dan macOS memakai / sedangkan Windows memakai \. Program yang merangkai path dengan penggabungan string mentah akan rusak begitu dipindahkan lintas platform. Package path/filepath menyelesaikan masalah tersebut, sementara package path menangani alamat bergaya slash yang tidak pernah menyentuh disk. Chapter ini membahas keduanya plus WalkDir untuk menelusuri direktori.
Merangkai Path dengan filepath.Join #
Fungsi filepath.Join menerima beberapa segmen lalu menyatukannya dengan pemisah yang benar untuk sistem operasi tempat program berjalan. Konstanta filepath.Separator memperlihatkan pemisah tersebut: / di Linux dan \ di Windows. Hasil Join juga selalu bersih — fungsi tersebut menjalankan Clean secara otomatis.
Fungsi filepath.Clean merapikan path berantakan: segmen . dibuang, segmen .. diselesaikan, dan pemisah ganda dilipat menjadi satu. Path belajar/./go/../go/latihan menjadi belajar/go/latihan — alamat yang sama jauh lebih mudah dibanding dan disimpan.
Memecah Path: Dir, Base, dan Ext #
Tiga fungsi kecil memecah path menjadi bagiannya tanpa menyentuh disk:
| Fungsi | Hasil untuk catatan/2026/laporan.txt | Kegunaan |
|---|---|---|
filepath.Dir | catatan/2026 | direktori pembungkus |
filepath.Base | laporan.txt | nama berkas paling ujung |
filepath.Ext | .txt | ekstensi, termasuk titiknya |
Ketiganya murni manipulasi teks, sehingga berkas yang dituju tidak perlu ada. Pola umumnya: Base untuk nama tampilan, Ext untuk memilih handler, dan Dir untuk membuat path baru di folder yang sama.
Path Absolut dengan filepath.Abs #
filepath.Abs("data/log.txt") mengembalikan alamat absolut dengan menggabungkan direktori kerja program saat ini. Program demo mencetak hasilnya secara nyata:
Package path untuk Alamat bergaya Slash #
Package path adalah saudara filepath yang selalu memakai /. Pilihannya bukan kebetulan: URL, kunci konfigurasi bertingkat, dan path di dalam fs.FS (misalnya hasil embed) memakai slash di semua platform.
| Package | Pemisah | Dipakai untuk |
|---|---|---|
path/filepath | mengikuti sistem operasi | berkas fisik di disk |
path | selalu / | URL, kunci konfigurasi, path fs.FS |
Menelusuri Direktori dengan WalkDir #
fs.WalkDir mengunjungi direktori induk, lalu seluruh isinya secara berurutan, dan memanggil fungsi callback untuk setiap entri. Mengembalikan nil dari callback membuat penelusuran lanjut; mengembalikan error membuat penelusuran berhenti. Program demo memakai testing/fstest.MapFS sebagai sistem berkas tiruan di memori: struktur proyek beserta isinya dideklarasikan sebagai map, sehingga penelusurannya deterministik tanpa menyentuh disk. Di program sungguhan, callback yang sama bekerja untuk direktori asli lewat os.DirFS maupun filepath.WalkDir.
Program Utuh #
Berkas filepath-demo.go menggabungkan seluruh materi di atas:
package main
import (
"fmt"
"io/fs"
"path"
"path/filepath"
"testing/fstest"
)
func main() {
// Join merangkai path dengan pemisah milik sistem operasi.
fmt.Println("join :", filepath.Join("belajar", "go", "latihan"))
fmt.Printf("separator: %q\n", string(filepath.Separator))
// Clean merapikan titik dan pemisah yang berlebih.
fmt.Println("clean :", filepath.Clean("belajar/./go/../go/latihan"))
// Dir, Base, dan Ext memecah path menjadi bagian-bagiannya.
berkas := "catatan/2026/laporan.txt"
fmt.Println("dir :", filepath.Dir(berkas))
fmt.Println("base :", filepath.Base(berkas))
fmt.Println("ext :", filepath.Ext(berkas))
// Abs menghasilkan path absolut dari direktori kerja saat ini.
absolut, err := filepath.Abs("data/log.txt")
if err != nil {
fmt.Println("abs gagal:", err)
return
}
fmt.Println("abs :", absolut)
// Package path selalu memakai slash, cocok untuk alamat bergaya URL.
fmt.Println("path url :", path.Join("/blog", "golang", "fmt"))
// WalkDir menelusuri struktur direktori secara berurutan.
sistem := fstest.MapFS{
"proyek/main.go": &fstest.MapFile{},
"proyek/internal/util.go": &fstest.MapFile{},
"proyek/internal/teks.go": &fstest.MapFile{},
"proyek/go.mod": &fstest.MapFile{},
}
kesalahan := fs.WalkDir(sistem, "proyek", func(jalur string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
jenis := "file"
if d.IsDir() {
jenis = "dir"
}
fmt.Printf("walk %-6s %s\n", jenis, jalur)
return nil
})
if kesalahan != nil {
fmt.Println("walk gagal:", kesalahan)
}
}Jalankan program dari folder chapter:
go run filepath-demo.goOutput yang Dihasilkan:
join : belajar/go/latihan
separator: "/"
clean : belajar/go/latihan
dir : catatan/2026
base : laporan.txt
ext : .txt
abs : /home/z/my-project/content/go/standard-library/filepath-dan-path/data/log.txt
path url : /blog/golang/fmt
walk dir proyek
walk file proyek/go.mod
walk dir proyek/internal
walk file proyek/internal/teks.go
walk file proyek/internal/util.go
walk file proyek/main.goMari kita telaah baris demi baris program di atas:
- Baris 13-14:
filepath.Joinmerangkai tiga segmen menjadi satu path portable, lalufilepath.Separatordicetak untuk memperlihatkan pemisah platform saat ini. - Baris 17:
filepath.Cleanmerapikan segmen.dan..hingga tersisa path paling ringkas. - Baris 20-23:
Dir,Base, danExtmemecah satu path menjadi tiga bagian tanpa membaca berkas. - Baris 26-31:
filepath.Absmengubah path relatif menjadi absolut berdasarkan direktori kerja; error yang mungkin terjadi tetap diperiksa. - Baris 34:
path.Joinmerangkai segmen bergaya URL yang selalu memakai slash. - Baris 37-42:
fstest.MapFSmendeklarasikan struktur direktoriproyeksebagai map di memori. - Baris 43-53: callback
fs.WalkDirmemberi labeldirataufilepada setiap entri; entri anak diurutkan secara alfabetis sehingga urutan cetak stabil. - Baris 54-56: error penelusuran diperiksa setelah
WalkDirselesai — pola yang sama denganScanner.Err()pada chapterbufio.
Referensi #
- Dokumentasi path/filepath — seluruh fungsi manipulasi path.
- testing/fstest
—
MapFSsebagai sistem berkas di memori.
Path kini tersusun rapi lintas platform. Chapter berikutnya menghadapi dimensi lain yang setiap program sadari: waktu — dari memformat tanggal sampai menjadwalkan pekerjaan dengan Timer dan Ticker di package time.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
filepath-demo.go
Unduh berkaspackage main
import (
"fmt"
"io/fs"
"path"
"path/filepath"
"testing/fstest"
)
func main() {
// Join merangkai path dengan pemisah milik sistem operasi.
fmt.Println("join :", filepath.Join("belajar", "go", "latihan"))
fmt.Printf("separator: %q\n", string(filepath.Separator))
// Clean merapikan titik dan pemisah yang berlebih.
fmt.Println("clean :", filepath.Clean("belajar/./go/../go/latihan"))
// Dir, Base, dan Ext memecah path menjadi bagian-bagiannya.
berkas := "catatan/2026/laporan.txt"
fmt.Println("dir :", filepath.Dir(berkas))
fmt.Println("base :", filepath.Base(berkas))
fmt.Println("ext :", filepath.Ext(berkas))
// Abs menghasilkan path absolut dari direktori kerja saat ini.
absolut, err := filepath.Abs("data/log.txt")
if err != nil {
fmt.Println("abs gagal:", err)
return
}
fmt.Println("abs :", absolut)
// Package path selalu memakai slash, cocok untuk alamat bergaya URL.
fmt.Println("path url :", path.Join("/blog", "golang", "fmt"))
// WalkDir menelusuri struktur direktori secara berurutan.
sistem := fstest.MapFS{
"proyek/main.go": &fstest.MapFile{},
"proyek/internal/util.go": &fstest.MapFile{},
"proyek/internal/teks.go": &fstest.MapFile{},
"proyek/go.mod": &fstest.MapFile{},
}
kesalahan := fs.WalkDir(sistem, "proyek", func(jalur string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
jenis := "file"
if d.IsDir() {
jenis = "dir"
}
fmt.Printf("walk %-6s %s\n", jenis, jalur)
return nil
})
if kesalahan != nil {
fmt.Println("walk gagal:", kesalahan)
}
}