File Operations
Go menyediakan berbagai package untuk operasi file seperti os, io, ioutil, dan path/filepath. Tutorial ini akan menunjukkan cara melakukan berbagai operasi file.
Contoh Masalah
Bagaimana cara:
- Membaca dan menulis file
- Mengelola direktori
- Mencari dan memfilter file
- Menangani path file
Penyelesaian
package main
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
)
// 1. Basic file operations
func basicFileOperations() error {
// Create file
file, err := os.Create("test.txt")
if err != nil {
return err
}
defer file.Close()
// Write string
content := "Hello, World!\nThis is a test file.\n"
_, err = file.WriteString(content)
if err != nil {
return err
}
// Read entire file
data, err := ioutil.ReadFile("test.txt")
if err != nil {
return err
}
fmt.Printf("File contents:\n%s", string(data))
return nil
}
// 2. Buffered reading and writing
func bufferedOperations() error {
// Write with buffer
file, err := os.Create("buffered.txt")
if err != nil {
return err
}
defer file.Close()
writer := bufio.NewWriter(file)
for i := 0; i < 5; i++ {
fmt.Fprintf(writer, "Line %d\n", i+1)
}
writer.Flush()
// Read with buffer
file, err = os.Open("buffered.txt")
if err != nil {
return err
}
defer file.Close()
reader := bufio.NewReader(file)
for {
line, err := reader.ReadString('\n')
if err == io.EOF {
break
}
if err != nil {
return err
}
fmt.Printf("Read: %s", line)
}
return nil
}
// 3. Directory operations
func directoryOperations() error {
// Create directory
err := os.MkdirAll("testdir/subdir", 0755)
if err != nil {
return err
}
// Create some test files
for i := 1; i <= 3; i++ {
filename := fmt.Sprintf("testdir/file%d.txt", i)
if err := ioutil.WriteFile(filename, []byte("test"), 0644); err != nil {
return err
}
}
// List directory
files, err := ioutil.ReadDir("testdir")
if err != nil {
return err
}
fmt.Println("\nDirectory contents:")
for _, file := range files {
fmt.Printf("- %s (dir: %v, size: %d bytes)\n",
file.Name(), file.IsDir(), file.Size())
}
return nil
}
// 4. File walking
func walkDirectory(root string) error {
return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
rel, err := filepath.Rel(root, path)
if err != nil {
return err
}
fmt.Printf("%s: %d bytes\n", rel, info.Size())
return nil
})
}
// 5. File filtering
func findFiles(root, pattern string) ([]string, error) {
var matches []string
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
if matched, err := filepath.Match(pattern, filepath.Base(path)); err != nil {
return err
} else if matched {
matches = append(matches, path)
}
return nil
})
return matches, err
}
// 6. File copy
func copyFile(src, dst string) error {
source, err := os.Open(src)
if err != nil {
return err
}
defer source.Close()
destination, err := os.Create(dst)
if err != nil {
return err
}
defer destination.Close()
_, err = io.Copy(destination, source)
return err
}
// 7. File watcher
func watchFile(filename string, duration time.Duration) error {
initialStat, err := os.Stat(filename)
if err != nil {
return err
}
for {
time.Sleep(duration)
stat, err := os.Stat(filename)
if err != nil {
return err
}
if stat.ModTime() != initialStat.ModTime() {
fmt.Printf("File %s has been modified\n", filename)
initialStat = stat
}
}
}
func main() {
// Basic file operations
fmt.Println("Basic file operations:")
if err := basicFileOperations(); err != nil {
fmt.Printf("Error: %v\n", err)
}
// Buffered operations
fmt.Println("\nBuffered operations:")
if err := bufferedOperations(); err != nil {
fmt.Printf("Error: %v\n", err)
}
// Directory operations
fmt.Println("\nDirectory operations:")
if err := directoryOperations(); err != nil {
fmt.Printf("Error: %v\n", err)
}
// Walk directory
fmt.Println("\nWalking directory:")
if err := walkDirectory("testdir"); err != nil {
fmt.Printf("Error: %v\n", err)
}
// Find files
fmt.Println("\nFinding files:")
matches, err := findFiles("testdir", "*.txt")
if err != nil {
fmt.Printf("Error: %v\n", err)
} else {
fmt.Println("Matching files:", strings.Join(matches, ", "))
}
// Copy file
fmt.Println("\nCopying file:")
if err := copyFile("test.txt", "test_copy.txt"); err != nil {
fmt.Printf("Error: %v\n", err)
}
// Start file watcher in goroutine
go func() {
fmt.Println("\nWatching test.txt for changes...")
if err := watchFile("test.txt", time.Second); err != nil {
fmt.Printf("Error: %v\n", err)
}
}()
// Cleanup
time.Sleep(time.Second * 2)
os.RemoveAll("testdir")
os.Remove("test.txt")
os.Remove("buffered.txt")
os.Remove("test_copy.txt")
}
Penjelasan Kode
Basic Operations
- Create/Delete
- Read/Write
- File info
Advanced Features
- Buffered I/O
- Directory walking
- File watching
Common Tasks
- File copying
- Pattern matching
- Path manipulation
Output
Basic file operations:
File contents:
Hello, World!
This is a test file.
Buffered operations:
Read: Line 1
Read: Line 2
Read: Line 3
Read: Line 4
Read: Line 5
Directory operations:
Directory contents:
- file1.txt (dir: false, size: 4 bytes)
- file2.txt (dir: false, size: 4 bytes)
- file3.txt (dir: false, size: 4 bytes)
- subdir (dir: true, size: 0 bytes)
Walking directory:
.: 0 bytes
file1.txt: 4 bytes
file2.txt: 4 bytes
file3.txt: 4 bytes
subdir: 0 bytes
Finding files:
Matching files: testdir/file1.txt, testdir/file2.txt, testdir/file3.txt
Copying file:
File copied successfully
Watching test.txt for changes...
Tips
- Selalu tutup file
- Gunakan defer
- Handle error dengan baik
- Perhatikan permission
- Gunakan path/filepath