🎯 Exemples recommandés
Balanced sample collections from various categories for you to explore
Exemples d'Opérations sur Fichiers Web Go
Exemples d'opérations sur fichiers Web Go incluant lecture/écriture de fichiers texte, copier/déplacer, parcours de répertoires et validation de fichiers
💻 Lecture/Écriture de Fichiers Texte go
🟢 simple
⭐⭐
Lire et écrire des fichiers texte avec diverses options de codification en utilisant Go file I/O
⏱️ 20 min
🏷️ go, web, file operations
Prerequisites:
Basic Go, File I/O, os package
// Web Go Text File Read/Write Examples
// Using Go file I/O for file operations
package main
import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"unicode/utf8"
)
// 1. Reading Text Files
// ReadTextFile reads a text file and returns its content
func ReadTextFile(filePath string) (string, error) {
content, err := ioutil.ReadFile(filePath)
if err != nil {
return "", fmt.Errorf("error reading file: %v", err)
}
return string(content), nil
}
// ReadTextFileWithEncoding reads a text file with specific encoding
func ReadTextFileWithEncoding(filePath string, encoding string) (string, error) {
// Go primarily works with UTF-8, but we can read and validate
content, err := ioutil.ReadFile(filePath)
if err != nil {
return "", fmt.Errorf("error reading file: %v", err)
}
// Validate UTF-8
if !utf8.Valid(content) {
return "", fmt.Errorf("file contains invalid UTF-8 sequences")
}
return string(content), nil
}
// ReadTextFileLineByLine reads a text file line by line
func ReadTextFileLineByLine(filePath string) ([]string, error) {
file, err := os.Open(filePath)
if err != nil {
return nil, fmt.Errorf("error opening file: %v", err)
}
defer file.Close()
var lines []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("error reading file: %v", err)
}
return lines, nil
}
// ReadTextFileInChunks reads a text file in chunks
func ReadTextFileInChunks(filePath string, chunkSize int) ([]string, error) {
file, err := os.Open(filePath)
if err != nil {
return nil, fmt.Errorf("error opening file: %v", err)
}
defer file.Close()
var chunks []string
buffer := make([]byte, chunkSize)
for {
n, err := file.Read(buffer)
if err != nil && err != io.EOF {
return nil, fmt.Errorf("error reading file: %v", err)
}
if n == 0 {
break
}
chunks = append(chunks, string(buffer[:n]))
}
return chunks, nil
}
// ReadTextFileWithBuffer reads a text file using buffered I/O
func ReadTextFileWithBuffer(filePath string) (string, error) {
file, err := os.Open(filePath)
if err != nil {
return "", fmt.Errorf("error opening file: %v", err)
}
defer file.Close()
var buffer bytes.Buffer
_, err = io.Copy(&buffer, file)
if err != nil {
return "", fmt.Errorf("error reading file: %v", err)
}
return buffer.String(), nil
}
// 2. Writing Text Files
// WriteTextFile writes text content to a file
func WriteTextFile(filePath string, content string) error {
err := ioutil.WriteFile(filePath, []byte(content), 0644)
if err != nil {
return fmt.Errorf("error writing file: %v", err)
}
return nil
}
// WriteTextLines writes a list of lines to a text file
func WriteTextLines(filePath string, lines []string) error {
file, err := os.Create(filePath)
if err != nil {
return fmt.Errorf("error creating file: %v", err)
}
defer file.Close()
writer := bufio.NewWriter(file)
for _, line := range lines {
_, err := writer.WriteString(line + "\n")
if err != nil {
return fmt.Errorf("error writing to file: %v", err)
}
}
return writer.Flush()
}
// WriteTextFileWithPermissions writes text content with specific permissions
func WriteTextFileWithPermissions(filePath string, content string, perm os.FileMode) error {
err := ioutil.WriteFile(filePath, []byte(content), perm)
if err != nil {
return fmt.Errorf("error writing file: %v", err)
}
return nil
}
// AppendToTextFile appends text content to an existing file
func AppendToTextFile(filePath string, content string) error {
file, err := os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
return fmt.Errorf("error opening file: %v", err)
}
defer file.Close()
_, err = file.WriteString(content)
if err != nil {
return fmt.Errorf("error appending to file: %v", err)
}
return nil
}
// WriteTextFileAtomic writes content atomically (using temp file)
func WriteTextFileAtomic(filePath string, content string) error {
// Write to temporary file
tempPath := filePath + ".tmp"
err := ioutil.WriteFile(tempPath, []byte(content), 0644)
if err != nil {
return fmt.Errorf("error writing temp file: %v", err)
}
// Rename atomically
err = os.Rename(tempPath, filePath)
if err != nil {
os.Remove(tempPath) // Cleanup
return fmt.Errorf("error renaming file: %v", err)
}
return nil
}
// 3. File Info Helper
// GetFileSize gets the size of a file in bytes
func GetFileSize(filePath string) (int64, error) {
info, err := os.Stat(filePath)
if err != nil {
return 0, fmt.Errorf("error getting file info: %v", err)
}
return info.Size(), nil
}
// GetFileExtension gets the file extension
func GetFileExtension(filePath string) string {
return filepath.Ext(filePath)
}
// GetFileNameWithoutExtension gets the file name without extension
func GetFileNameWithoutExtension(filePath string) string {
return strings.TrimSuffix(filepath.Base(filePath), filepath.Ext(filePath))
}
// FormatFileSize formats file size in human-readable format
func FormatFileSize(bytes int64) string {
const (
KB = 1024
MB = KB * 1024
GB = MB * 1024
TB = GB * 1024
)
switch {
case bytes >= TB:
return fmt.Sprintf("%.2f TB", float64(bytes)/float64(TB))
case bytes >= GB:
return fmt.Sprintf("%.2f GB", float64(bytes)/float64(GB))
case bytes >= MB:
return fmt.Sprintf("%.2f MB", float64(bytes)/float64(MB))
case bytes >= KB:
return fmt.Sprintf("%.2f KB", float64(bytes)/float64(KB))
default:
return fmt.Sprintf("%d B", bytes)
}
}
// GetFileDetails gets detailed information about a file
func GetFileDetails(filePath string) (map[string]interface{}, error) {
info, err := os.Stat(filePath)
if err != nil {
return nil, fmt.Errorf("error getting file info: %v", err)
}
absPath, err := filepath.Abs(filePath)
if err != nil {
return nil, fmt.Errorf("error getting absolute path: %v", err)
}
return map[string]interface{}{
"name": filepath.Base(filePath),
"size": info.Size(),
"readable_size": FormatFileSize(info.Size()),
"extension": GetFileExtension(filePath),
"modified_time": info.ModTime(),
"is_file": !info.IsDir(),
"is_dir": info.IsDir(),
"absolute_path": absPath,
"mode": info.Mode(),
}, nil
}
// 4. File Validation
// FileExists checks if a file exists
func FileExists(filePath string) bool {
_, err := os.Stat(filePath)
return !os.IsNotExist(err)
}
// IsFile checks if path is a file
func IsFile(filePath string) bool {
info, err := os.Stat(filePath)
if err != nil {
return false
}
return !info.IsDir()
}
// IsDirectory checks if path is a directory
func IsDirectory(dirPath string) bool {
info, err := os.Stat(dirPath)
if err != nil {
return false
}
return info.IsDir()
}
// ValidateFile validates file properties
func ValidateFile(filePath string, maxSizeMB int64) (map[string]interface{}, error) {
result := make(map[string]interface{})
result["valid"] = true
result["errors"] = []string{}
if !FileExists(filePath) {
result["valid"] = false
result["errors"] = append(result["errors"].([]string), "File does not exist")
return result, nil
}
if !IsFile(filePath) {
result["valid"] = false
result["errors"] = append(result["errors"].([]string), "Path is not a file")
return result, nil
}
if maxSizeMB > 0 {
size, err := GetFileSize(filePath)
if err != nil {
result["valid"] = false
result["errors"] = append(result["errors"].([]string), fmt.Sprintf("Error getting file size: %v", err))
return result, nil
}
sizeMB := size / (1024 * 1024)
if sizeMB > maxSizeMB {
result["valid"] = false
result["errors"] = append(result["errors"].([]string), fmt.Sprintf("File size (%.2fMB) exceeds limit (%dMB)", float64(sizeMB), maxSizeMB))
}
}
return result, nil
}
// 5. Batch File Operations
// ReadMultipleFiles reads multiple text files
func ReadMultipleFiles(filePaths []string) map[string]string {
results := make(map[string]string)
for _, filePath := range filePaths {
content, err := ReadTextFile(filePath)
if err == nil {
results[filePath] = content
}
}
return results
}
// BatchWriteFiles writes to multiple files
func BatchWriteFiles(fileDataMap map[string]string) ([]string, []string) {
var successful []string
var failed []string
for filePath, content := range fileDataMap {
err := WriteTextFile(filePath, content)
if err == nil {
successful = append(successful, filePath)
} else {
failed = append(failed, filePath)
}
}
return successful, failed
}
// SearchInFiles searches for text in multiple files
func SearchInFiles(filePaths []string, searchText string, caseSensitive bool) map[string][]int {
results := make(map[string][]int)
if !caseSensitive {
searchText = strings.ToLower(searchText)
}
for _, filePath := range filePaths {
lines, err := ReadTextFileLineByLine(filePath)
if err != nil {
continue
}
var matchingLines []int
for i, line := range lines {
searchLine := line
if !caseSensitive {
searchLine = strings.ToLower(line)
}
if strings.Contains(searchLine, searchText) {
matchingLines = append(matchingLines, i+1)
}
}
if len(matchingLines) > 0 {
results[filePath] = matchingLines
}
}
return results
}
// 6. File Encoding Utilities
// DetectFileEncoding detects file encoding (simplified)
func DetectFileEncoding(filePath string) (string, error) {
content, err := ioutil.ReadFile(filePath)
if err != nil {
return "", err
}
// Check for BOM
if len(content) >= 3 && content[0] == 0xEF && content[1] == 0xBB && content[2] == 0xBF {
return "UTF-8 with BOM", nil
}
// Validate UTF-8
if utf8.Valid(content) {
return "UTF-8", nil
}
// Default to ASCII/unknown
return "ASCII/Unknown", nil
}
// ConvertFileEncoding converts file from one encoding to another
func ConvertFileEncoding(inputPath, outputPath string, fromEncoding, toEncoding string) error {
// Read input file
content, err := ioutil.ReadFile(inputPath)
if err != nil {
return fmt.Errorf("error reading input file: %v", err)
}
// Write to output file
err = ioutil.WriteFile(outputPath, content, 0644)
if err != nil {
return fmt.Errorf("error writing output file: %v", err)
}
return nil
}
// Usage Examples
func main() {
fmt.Println("=== Web Go Text File Read/Write Examples ===\n")
// 1. Read text file
fmt.Println("--- 1. Read Text File ---")
content, err := ReadTextFile("example.txt")
if err == nil {
fmt.Printf("Content length: %d characters\n", len(content))
}
// 2. Read line by line
fmt.Println("\n--- 2. Read Line by Line ---")
lines, err := ReadTextFileLineByLine("example.txt")
if err == nil {
fmt.Printf("Number of lines: %d\n", len(lines))
fmt.Printf("First 3 lines: %v\n", lines[:min(3, len(lines))])
}
// 3. Write text file
fmt.Println("\n--- 3. Write Text File ---")
err = WriteTextFile("output.txt", "Hello, World!\nThis is a new file.")
if err == nil {
fmt.Println("File written successfully")
}
// 4. Write lines
fmt.Println("\n--- 4. Write Lines ---")
linesToWrite := []string{"Line 1", "Line 2", "Line 3"}
err = WriteTextLines("lines.txt", linesToWrite)
if err == nil {
fmt.Println("Lines file written successfully")
}
// 5. Get file details
fmt.Println("\n--- 5. File Details ---")
details, err := GetFileDetails("example.txt")
if err == nil {
fmt.Printf("Name: %v\n", details["name"])
fmt.Printf("Size: %v\n", details["readable_size"])
fmt.Printf("Extension: %v\n", details["extension"])
}
// 6. File validation
fmt.Println("\n--- 6. File Validation ---")
validation, err := ValidateFile("example.txt", 1)
if err == nil {
fmt.Printf("Valid: %v\n", validation["valid"])
}
fmt.Println("\n=== All Text File Operations Completed ===")
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
💻 Copier/Déplacer des Fichiers go
🟡 intermediate
⭐⭐⭐
Copier et déplacer des fichiers avec suivi de progression et gestion des erreurs
⏱️ 25 min
🏷️ go, web, file operations
Prerequisites:
Intermediate Go, io package, filepath package
// Web Go File Copy/Move Examples
// File copy and move operations with progress tracking
package main
import (
"fmt"
"io"
"os"
"path/filepath"
"time"
)
// 1. File Copy Operations
// CopyFile copies a file from source to destination
func CopyFile(sourcePath, destinationPath string) error {
sourceFile, err := os.Open(sourcePath)
if err != nil {
return fmt.Errorf("error opening source file: %v", err)
}
defer sourceFile.Close()
// Ensure destination directory exists
destDir := filepath.Dir(destinationPath)
if err := os.MkdirAll(destDir, 0755); err != nil {
return fmt.Errorf("error creating destination directory: %v", err)
}
destFile, err := os.Create(destinationPath)
if err != nil {
return fmt.Errorf("error creating destination file: %v", err)
}
defer destFile.Close()
// Copy contents
_, err = io.Copy(destFile, sourceFile)
if err != nil {
return fmt.Errorf("error copying file: %v", err)
}
// Copy file permissions
sourceInfo, err := os.Stat(sourcePath)
if err != nil {
return fmt.Errorf("error getting source file info: %v", err)
}
err = os.Chmod(destinationPath, sourceInfo.Mode())
if err != nil {
return fmt.Errorf("error setting file permissions: %v", err)
}
return nil
}
// CopyFileWithBuffer copies a file using a buffer
func CopyFileWithBuffer(sourcePath, destinationPath string, bufferSize int) error {
sourceFile, err := os.Open(sourcePath)
if err != nil {
return fmt.Errorf("error opening source file: %v", err)
}
defer sourceFile.Close()
destDir := filepath.Dir(destinationPath)
if err := os.MkdirAll(destDir, 0755); err != nil {
return fmt.Errorf("error creating destination directory: %v", err)
}
destFile, err := os.Create(destinationPath)
if err != nil {
return fmt.Errorf("error creating destination file: %v", err)
}
defer destFile.Close()
buffer := make([]byte, bufferSize)
_, err = io.CopyBuffer(destFile, sourceFile, buffer)
if err != nil {
return fmt.Errorf("error copying file: %v", err)
}
sourceInfo, err := os.Stat(sourcePath)
if err != nil {
return fmt.Errorf("error getting source file info: %v", err)
}
return os.Chmod(destinationPath, sourceInfo.Mode())
}
// CopyFileWithProgress copies a file with progress tracking
func CopyFileWithProgress(sourcePath, destinationPath string, progressCallback func(written, total int64)) error {
sourceFile, err := os.Open(sourcePath)
if err != nil {
return fmt.Errorf("error opening source file: %v", err)
}
defer sourceFile.Close()
sourceInfo, err := sourceFile.Stat()
if err != nil {
return fmt.Errorf("error getting source file info: %v", err)
}
destDir := filepath.Dir(destinationPath)
if err := os.MkdirAll(destDir, 0755); err != nil {
return fmt.Errorf("error creating destination directory: %v", err)
}
destFile, err := os.Create(destinationPath)
if err != nil {
return fmt.Errorf("error creating destination file: %v", err)
}
defer destFile.Close()
// Copy with progress
buffer := make([]byte, 32*1024) // 32KB buffer
var written int64
for {
n, err := sourceFile.Read(buffer)
if n > 0 {
w, writeErr := destFile.Write(buffer[:n])
if writeErr != nil {
return fmt.Errorf("error writing to destination: %v", writeErr)
}
written += int64(w)
if progressCallback != nil {
progressCallback(written, sourceInfo.Size())
}
}
if err != nil {
if err == io.EOF {
break
}
return fmt.Errorf("error reading source: %v", err)
}
}
// Copy permissions
return os.Chmod(destinationPath, sourceInfo.Mode())
}
// 2. File Move Operations
// MoveFile moves a file from source to destination
func MoveFile(sourcePath, destinationPath string) error {
// Try rename first (fastest if on same filesystem)
err := os.Rename(sourcePath, destinationPath)
if err == nil {
return nil
}
// If rename fails, copy and delete
if err := CopyFile(sourcePath, destinationPath); err != nil {
return fmt.Errorf("error copying file: %v", err)
}
// Remove source file
return os.Remove(sourcePath)
}
// MoveFileAtomic moves a file atomically
func MoveFileAtomic(sourcePath, destinationPath string) error {
// Ensure destination directory exists
destDir := filepath.Dir(destinationPath)
if err := os.MkdirAll(destDir, 0755); err != nil {
return fmt.Errorf("error creating destination directory: %v", err)
}
// Atomic rename
return os.Rename(sourcePath, destinationPath)
}
// 3. Directory Operations
// CopyDirectory copies entire directory recursively
func CopyDirectory(sourceDir, destinationDir string) error {
sourceInfo, err := os.Stat(sourceDir)
if err != nil {
return fmt.Errorf("error getting source directory info: %v", err)
}
// Create destination directory
if err := os.MkdirAll(destinationDir, sourceInfo.Mode()); err != nil {
return fmt.Errorf("error creating destination directory: %v", err)
}
// Read source directory
entries, err := os.ReadDir(sourceDir)
if err != nil {
return fmt.Errorf("error reading source directory: %v", err)
}
// Copy each entry
for _, entry := range entries {
sourcePath := filepath.Join(sourceDir, entry.Name())
destPath := filepath.Join(destinationDir, entry.Name())
if entry.IsDir() {
// Recursively copy subdirectory
if err := CopyDirectory(sourcePath, destPath); err != nil {
return err
}
} else {
// Copy file
if err := CopyFile(sourcePath, destPath); err != nil {
return err
}
}
}
return nil
}
// CopyDirectoryWithProgress copies directory with progress tracking
func CopyDirectoryWithProgress(sourceDir, destinationDir string, progressCallback func(current, total int, filename string)) error {
// Count total files first
totalFiles := 0
filepath.Walk(sourceDir, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
totalFiles++
}
return nil
})
copiedFiles := 0
// Copy files
return filepath.Walk(sourceDir, func(sourcePath string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
// Calculate destination path
relPath, err := filepath.Rel(sourceDir, sourcePath)
if err != nil {
return err
}
destPath := filepath.Join(destinationDir, relPath)
// Ensure destination directory exists
destDir := filepath.Dir(destPath)
if err := os.MkdirAll(destDir, 0755); err != nil {
return err
}
// Copy file
if err := CopyFile(sourcePath, destPath); err != nil {
return err
}
copiedFiles++
if progressCallback != nil {
progressCallback(copiedFiles, totalFiles, filepath.Base(sourcePath))
}
return nil
})
}
// MoveDirectory moves directory from source to destination
func MoveDirectory(sourceDir, destinationDir string) error {
// Try atomic rename first
err := os.Rename(sourceDir, destinationDir)
if err == nil {
return nil
}
// If rename fails, copy and delete
if err := CopyDirectory(sourceDir, destinationDir); err != nil {
return fmt.Errorf("error copying directory: %v", err)
}
return os.RemoveAll(sourceDir)
}
// 4. Batch Operations
// BatchRenameFiles renames files in a directory using a pattern
func BatchRenameFiles(directory string, renameFunc func(string) string) ([]string, []string) {
var renamed []string
var failed []string
entries, err := os.ReadDir(directory)
if err != nil {
failed = append(failed, directory)
return renamed, failed
}
for _, entry := range entries {
if entry.IsDir() {
continue
}
oldPath := filepath.Join(directory, entry.Name())
newName := renameFunc(entry.Name())
newPath := filepath.Join(directory, newName)
if err := os.Rename(oldPath, newPath); err != nil {
failed = append(failed, oldPath)
} else {
renamed = append(renamed, oldPath+" -> "+newPath)
}
}
return renamed, failed
}
// 5. Safe File Operations
// SafeCopy copies file with safety checks
func SafeCopy(sourcePath, destinationPath string) error {
// Validate source
if _, err := os.Stat(sourcePath); err != nil {
return fmt.Errorf("source file error: %v", err)
}
// Check if destination exists
if _, err := os.Stat(destinationPath); err == nil {
return fmt.Errorf("destination file already exists")
}
return CopyFile(sourcePath, destinationPath)
}
// SafeMove moves file with safety checks
func SafeMove(sourcePath, destinationPath string) error {
// Validate source
if _, err := os.Stat(sourcePath); err != nil {
return fmt.Errorf("source file error: %v", err)
}
// Check if destination exists
if _, err := os.Stat(destinationPath); err == nil {
return fmt.Errorf("destination file already exists")
}
// Ensure destination directory exists
destDir := filepath.Dir(destinationPath)
if err := os.MkdirAll(destDir, 0755); err != nil {
return fmt.Errorf("error creating destination directory: %v", err)
}
return MoveFile(sourcePath, destinationPath)
}
// 6. Backup and Restore
// CreateBackup creates backup of files/directories
func CreateBackup(sourcePaths []string, backupDir string, useTimestamp bool) (string, error) {
var backupPath string
if useTimestamp {
timestamp := time.Now().Format("20060102_150405")
backupPath = filepath.Join(backupDir, "backup_"+timestamp)
} else {
backupPath = filepath.Join(backupDir, "backup")
}
if err := os.MkdirAll(backupPath, 0755); err != nil {
return "", fmt.Errorf("error creating backup directory: %v", err)
}
for _, source := range sourcePaths {
dest := filepath.Join(backupPath, filepath.Base(source))
info, err := os.Stat(source)
if err != nil {
continue
}
if info.IsDir() {
if err := CopyDirectory(source, dest); err != nil {
return "", err
}
} else {
if err := CopyFile(source, dest); err != nil {
return "", err
}
}
}
return backupPath, nil
}
// RestoreFromBackup restores files from backup directory
func RestoreFromBackup(backupDir, targetDir string) error {
return CopyDirectory(backupDir, targetDir)
}
// Usage Examples
func main() {
fmt.Println("=== Web Go File Copy/Move Examples ===\n")
// 1. Copy file
fmt.Println("--- 1. Copy File ---")
err := CopyFile("source.txt", "copy.txt")
if err == nil {
fmt.Println("File copied successfully")
} else {
fmt.Printf("Error: %v\n", err)
}
// 2. Copy with progress
fmt.Println("\n--- 2. Copy with Progress ---")
err = CopyFileWithProgress("source.txt", "copy2.txt", func(written, total int64) {
fmt.Printf("Progress: %d/%d bytes (%.1f%%)\n", written, total, float64(written)/float64(total)*100)
})
if err == nil {
fmt.Println("File copied with progress successfully")
}
// 3. Move file
fmt.Println("\n--- 3. Move File ---")
err = MoveFile("old_name.txt", "new_name.txt")
if err == nil {
fmt.Println("File moved successfully")
}
// 4. Batch rename
fmt.Println("\n--- 4. Batch Rename ---")
renamed, failed := BatchRenameFiles(".", func(name string) string {
return strings.Replace(name, ".txt", ".bak", 1)
})
fmt.Printf("Renamed %d files\n", len(renamed))
fmt.Printf("Failed %d files\n", len(failed))
// 5. Backup
fmt.Println("\n--- 5. Backup ---")
backupPath, err := CreateBackup([]string{"important_file.txt", "important_dir"}, "backups", true)
if err == nil {
fmt.Printf("Backup created at: %s\n", backupPath)
}
fmt.Println("\n=== All File Copy/Move Examples Completed ===")
}
💻 Parcours de Répertoire go
🔴 complex
⭐⭐⭐⭐
Parcourir les répertoires en utilisant filepath.Walk, les motifs glob et l'exploration de fichiers
⏱️ 30 min
🏷️ go, web, file operations, directory
Prerequisites:
Advanced Go, filepath package, ioutil package
// Web Go Directory Traversal Examples
// Using filepath.Walk and glob patterns for directory operations
package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strings"
)
// 1. Directory Listing
// DirectoryContents represents contents of a directory
type DirectoryContents struct {
Directory string
Files []string
Directories []string
}
// ListDirectoryContents lists contents of a directory
func ListDirectoryContents(directory string, recursive bool) (*DirectoryContents, error) {
result := &DirectoryContents{
Directory: directory,
Files: []string{},
Directories: []string{},
}
if recursive {
err := filepath.Walk(directory, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() && path != directory {
result.Directories = append(result.Directories, path)
} else if !info.IsDir() {
result.Files = append(result.Files, path)
}
return nil
})
if err != nil {
return nil, fmt.Errorf("error walking directory: %v", err)
}
} else {
entries, err := ioutil.ReadDir(directory)
if err != nil {
return nil, fmt.Errorf("error reading directory: %v", err)
}
for _, entry := range entries {
fullPath := filepath.Join(directory, entry.Name())
if entry.IsDir() {
result.Directories = append(result.Directories, fullPath)
} else {
result.Files = append(result.Files, fullPath)
}
}
}
return result, nil
}
// TreeNode represents a node in the directory tree
type TreeNode struct {
Name string
Path string
IsDir bool
Children []*TreeNode
}
// ListDirectoryTree lists directory as a tree structure
func ListDirectoryTree(directory string, maxDepth int) (*TreeNode, error) {
return buildTree(directory, 0, maxDepth)
}
func buildTree(path string, depth, maxDepth int) (*TreeNode, error) {
if maxDepth >= 0 && depth > maxDepth {
return &TreeNode{
Name: filepath.Base(path),
Children: []*TreeNode{},
}, nil
}
info, err := os.Stat(path)
if err != nil {
return nil, err
}
node := &TreeNode{
Name: filepath.Base(path),
Path: path,
IsDir: info.IsDir(),
}
if info.IsDir() {
entries, err := ioutil.ReadDir(path)
if err != nil {
return node, nil
}
// Sort entries
sort.Slice(entries, func(i, j int) bool {
return entries[i].Name() < entries[j].Name()
})
for _, entry := range entries {
childPath := filepath.Join(path, entry.Name())
child, err := buildTree(childPath, depth+1, maxDepth)
if err != nil {
continue
}
node.Children = append(node.Children, child)
}
}
return node, nil
}
// PrintDirectoryTree prints directory tree structure
func PrintDirectoryTree(tree *TreeNode, indent int) {
prefix := strings.Repeat(" ", indent)
icon := "📁"
if !tree.IsDir {
icon = "📄"
}
fmt.Printf("%s%s %s\n", prefix, icon, tree.Name)
for _, child := range tree.Children {
PrintDirectoryTree(child, indent+1)
}
}
// 2. File Pattern Matching
// FindFilesByPattern finds files matching a pattern
func FindFilesByPattern(directory, pattern string) ([]string, error) {
var matches []string
err := filepath.Walk(directory, func(path string, info os.FileInfo, err error) error {
if err != nil {
return nil
}
if info.IsDir() {
return nil
}
matched, err := filepath.Match(pattern, filepath.Base(path))
if err != nil {
return nil
}
if matched {
matches = append(matches, path)
}
return nil
})
if err != nil {
return nil, err
}
return matches, nil
}
// FindFilesByExtension finds files with specific extension
func FindFilesByExtension(directory, extension string) ([]string, error) {
if !strings.HasPrefix(extension, ".") {
extension = "." + extension
}
return FindFilesByPattern(directory, "*"+extension)
}
// FindFilesByName finds files by name pattern
func FindFilesByName(directory, namePattern string) ([]string, error) {
return FindFilesByPattern(directory, namePattern)
}
// 3. Directory Statistics
// DirectoryStats represents statistics about a directory
type DirectoryStats struct {
TotalFiles int64
TotalDirectories int64
TotalSize int64
ExtensionCounts map[string]int
LargestFiles []FileEntry
}
// FileEntry represents a file entry with size
type FileEntry struct {
Path string
Size int64
}
// GetDirectoryStatistics gets statistics about a directory
func GetDirectoryStatistics(directory string) (*DirectoryStats, error) {
stats := &DirectoryStats{
ExtensionCounts: make(map[string]int),
LargestFiles: []FileEntry{},
}
err := filepath.Walk(directory, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
if path != directory {
stats.TotalDirectories++
}
return nil
}
stats.TotalFiles++
stats.TotalSize += info.Size()
// Track extensions
ext := strings.ToLower(filepath.Ext(path))
stats.ExtensionCounts[ext]++
// Track largest files
stats.LargestFiles = append(stats.LargestFiles, FileEntry{
Path: path,
Size: info.Size(),
})
return nil
})
if err != nil {
return nil, err
}
// Sort largest files
sort.Slice(stats.LargestFiles, func(i, j int) bool {
return stats.LargestFiles[i].Size > stats.LargestFiles[j].Size
})
// Keep top 10
if len(stats.LargestFiles) > 10 {
stats.LargestFiles = stats.LargestFiles[:10]
}
return stats, nil
}
// 4. File Search in Directory
// SearchInDirectory searches for text in files within a directory
func SearchInDirectory(directory, searchText, filePattern string) (map[string][]int, error) {
results := make(map[string][]int)
matches, err := FindFilesByPattern(directory, filePattern)
if err != nil {
return nil, err
}
for _, filePath := range matches {
matchingLines, err := searchInFile(filePath, searchText)
if err != nil {
continue
}
if len(matchingLines) > 0 {
results[filePath] = matchingLines
}
}
return results, nil
}
func searchInFile(filePath, searchText string) ([]int, error) {
content, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, err
}
lines := strings.Split(string(content), "\n")
var matchingLines []int
for i, line := range lines {
if strings.Contains(line, searchText) {
matchingLines = append(matchingLines, i+1)
}
}
return matchingLines, nil
}
// 5. Directory Comparison
// DirectoryComparison represents comparison results
type DirectoryComparison struct {
OnlyInDir1 []string
OnlyInDir2 []string
Different []string
Same []string
}
// CompareDirectories compares two directories and finds differences
func CompareDirectories(dir1, dir2 string) (*DirectoryComparison, error) {
result := &DirectoryComparison{
OnlyInDir1: []string{},
OnlyInDir2: []string{},
Different: []string{},
Same: []string{},
}
files1 := make(map[string]int64)
files2 := make(map[string]int64)
// Walk dir1
err := filepath.Walk(dir1, func(path string, info os.FileInfo, err error) error {
if err != nil || info.IsDir() {
return nil
}
relPath, err := filepath.Rel(dir1, path)
if err != nil {
return nil
}
files1[relPath] = info.Size()
return nil
})
if err != nil {
return nil, err
}
// Walk dir2
err = filepath.Walk(dir2, func(path string, info os.FileInfo, err error) error {
if err != nil || info.IsDir() {
return nil
}
relPath, err := filepath.Rel(dir2, path)
if err != nil {
return nil
}
files2[relPath] = info.Size()
return nil
})
if err != nil {
return nil, err
}
// Find files only in dir1
for path := range files1 {
if _, exists := files2[path]; !exists {
result.OnlyInDir1 = append(result.OnlyInDir1, path)
}
}
// Find files only in dir2
for path := range files2 {
if _, exists := files1[path]; !exists {
result.OnlyInDir2 = append(result.OnlyInDir2, path)
}
}
// Compare common files
for path := range files1 {
if size2, exists := files2[path]; exists {
if files1[path] == size2 {
result.Same = append(result.Same, path)
} else {
result.Different = append(result.Different, path)
}
}
}
return result, nil
}
// 6. Directory Cleanup
// CleanupDirectory cleans up directory by removing files matching patterns
func CleanupDirectory(directory string, dryRun bool, patterns []string) ([]string, []string) {
var deleted []string
var failed []string
if patterns == nil {
patterns = []string{"*.tmp", "*.log", "*.bak", "*~"}
}
entries, err := ioutil.ReadDir(directory)
if err != nil {
failed = append(failed, directory)
return deleted, failed
}
for _, entry := range entries {
if entry.IsDir() {
continue
}
fileName := entry.Name()
fullPath := filepath.Join(directory, fileName)
// Check if matches any pattern
matches := false
for _, pattern := range patterns {
matched, _ := filepath.Match(pattern, fileName)
if matched {
matches = true
break
}
}
if matches {
if dryRun {
fmt.Printf("Would delete: %s\n", fullPath)
deleted = append(deleted, fullPath)
} else {
if err := os.Remove(fullPath); err != nil {
failed = append(failed, fullPath)
} else {
deleted = append(deleted, fullPath)
}
}
}
}
return deleted, failed
}
// RemoveEmptyDirectories removes empty directories
func RemoveEmptyDirectories(directory string, recursive bool) int {
removedCount := 0
if recursive {
// Process subdirectories first (bottom-up)
filepath.Walk(directory, func(path string, info os.FileInfo, err error) error {
if err != nil || !info.IsDir() || path == directory {
return nil
}
if isEmptyDir(path) {
if err := os.Remove(path); err == nil {
removedCount++
fmt.Printf("Removed empty directory: %s\n", path)
}
}
return nil
})
}
// Remove the root directory if it's empty
if isEmptyDir(directory) {
if err := os.Remove(directory); err == nil {
removedCount++
fmt.Printf("Removed empty directory: %s\n", directory)
}
}
return removedCount
}
func isEmptyDir(dir string) bool {
entries, err := ioutil.ReadDir(dir)
if err != nil {
return false
}
return len(entries) == 0
}
// Usage Examples
func main() {
fmt.Println("=== Web Go Directory Traversal Examples ===\n")
// 1. List directory contents
fmt.Println("--- 1. List Directory Contents ---")
contents, err := ListDirectoryContents(".", false)
if err == nil {
fmt.Printf("Files: %d\n", len(contents.Files))
fmt.Printf("Directories: %d\n", len(contents.Directories))
}
// 2. Directory tree
fmt.Println("\n--- 2. Directory Tree ---")
tree, err := ListDirectoryTree(".", 2)
if err == nil {
PrintDirectoryTree(tree, 0)
}
// 3. Find files by pattern
fmt.Println("\n--- 3. Find Files by Pattern ---")
txtFiles, err := FindFilesByExtension(".", "txt")
if err == nil {
fmt.Printf("Text files: %d\n", len(txtFiles))
}
// 4. Directory statistics
fmt.Println("\n--- 4. Directory Statistics ---")
stats, err := GetDirectoryStatistics(".")
if err == nil {
fmt.Printf("Total files: %d\n", stats.TotalFiles)
fmt.Printf("Total size: %s\n", FormatFileSize(stats.TotalSize))
fmt.Printf("Extensions: %v\n", stats.ExtensionCounts)
}
// 5. Search in directory
fmt.Println("\n--- 5. Search in Directory ---")
searchResults, err := SearchInDirectory(".", "TODO", "*.txt")
if err == nil {
fmt.Printf("Files containing 'TODO': %d\n", len(searchResults))
}
// 6. Compare directories
fmt.Println("\n--- 6. Compare Directories ---")
comparison, err := CompareDirectories("dir1", "dir2")
if err == nil {
fmt.Printf("Only in dir1: %d\n", len(comparison.OnlyInDir1))
fmt.Printf("Only in dir2: %d\n", len(comparison.OnlyInDir2))
fmt.Printf("Different: %d\n", len(comparison.Different))
}
// 7. Cleanup
fmt.Println("\n--- 7. Cleanup ---")
deleted, _ := CleanupDirectory(".", true, []string{"*.tmp"})
fmt.Printf("Would delete %d files\n", len(deleted))
fmt.Println("\n=== All Directory Traversal Examples Completed ===")
}
// FormatFileSize formats file size in human-readable format
func FormatFileSize(bytes int64) string {
const (
KB = 1024
MB = KB * 1024
GB = MB * 1024
)
switch {
case bytes >= GB:
return fmt.Sprintf("%.2f GB", float64(bytes)/float64(GB))
case bytes >= MB:
return fmt.Sprintf("%.2f MB", float64(bytes)/float64(MB))
case bytes >= KB:
return fmt.Sprintf("%.2f KB", float64(bytes)/float64(KB))
default:
return fmt.Sprintf("%d B", bytes)
}
}