跳转至

第七章:标准库

7.1 文件操作

读写文件

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
)

func main() {
    // 写文件
    err := os.WriteFile("test.txt", []byte("Hello, Go!"), 0644)
    if err != nil {
        panic(err)
    }

    // 读文件
    data, err := os.ReadFile("test.txt")
    if err != nil {
        panic(err)
    }
    fmt.Println(string(data))

    // 打开文件
    file, err := os.Open("test.txt")
    if err != nil {
        panic(err)
    }
    defer file.Close()

    // 缓冲读取
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }

    // 追加写入
    f, _ := os.OpenFile("test.txt", os.O_APPEND|os.O_WRONLY, 0644)
    f.WriteString("\n新的一行")
    f.Close()

    // 复制文件
    src, _ := os.Open("test.txt")
    dst, _ := os.Create("test_copy.txt")
    io.Copy(dst, src)
    src.Close()
    dst.Close()
}

文件信息

package main

import (
    "fmt"
    "os"
    "path/filepath"
)

func main() {
    // 文件信息
    info, _ := os.Stat("test.txt")
    fmt.Printf("名称: %s\n", info.Name())
    fmt.Printf("大小: %d 字节\n", info.Size())
    fmt.Printf("模式: %v\n", info.Mode())
    fmt.Printf("修改时间: %v\n", info.ModTime())
    fmt.Printf("是目录: %v\n", info.IsDir())

    // 路径操作
    fmt.Println(filepath.Join("dir", "subdir", "file.txt"))
    fmt.Println(filepath.Base("/path/to/file.txt"))
    fmt.Println(filepath.Dir("/path/to/file.txt"))
    fmt.Println(filepath.Ext("/path/to/file.txt"))

    // 遍历目录
    filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
        fmt.Println(path)
        return nil
    })
}

7.2 网络编程

HTTP 客户端

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "time"
)

func main() {
    client := &http.Client{
        Timeout: 10 * time.Second,
    }

    // GET 请求
    resp, err := client.Get("https://httpbin.org/get")
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)
    fmt.Println(string(body))

    // POST 请求
    data := map[string]string{"name": "Go"}
    jsonData, _ := json.Marshal(data)
    resp, _ = client.Post(
        "https://httpbin.org/post",
        "application/json",
        bytes.NewBuffer(jsonData),
    )
    defer resp.Body.Close()

    // 带请求头
    req, _ := http.NewRequest("GET", "https://httpbin.org/headers", nil)
    req.Header.Set("Authorization", "Bearer token123")
    resp, _ = client.Do(req)
    defer resp.Body.Close()
}

HTTP 服务器

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)

type Response struct {
    Message string `json:"message"`
    Status  int    `json:"status"`
}

func helloHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(Response{
        Message: "Hello, Go!",
        Status:  200,
    })
}

func main() {
    http.HandleFunc("/hello", helloHandler)

    // 静态文件
    http.Handle("/static/", http.StripPrefix(
        "/static/",
        http.FileServer(http.Dir("./static")),
    ))

    fmt.Println("服务器启动在 :8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

7.3 JSON 处理

package main

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name  string   `json:"name"`
    Age   int      `json:"age"`
    Email string   `json:"email,omitempty"`
    Tags  []string `json:"tags,omitempty"`
}

func main() {
    // 结构体转 JSON
    p := Person{
        Name: "张三",
        Age:  25,
        Tags: []string{"go", "backend"},
    }

    data, _ := json.Marshal(p)
    fmt.Println(string(data))

    // 格式化输出
    data, _ = json.MarshalIndent(p, "", "  ")
    fmt.Println(string(data))

    // JSON 转结构体
    jsonStr := `{"name":"李四","age":30,"email":"lisi@example.com"}`
    var p2 Person
    json.Unmarshal([]byte(jsonStr), &p2)
    fmt.Println(p2)

    // 处理未知结构
    var m map[string]interface{}
    json.Unmarshal([]byte(jsonStr), &m)
    fmt.Println(m["name"])

    // 流式处理
    decoder := json.NewDecoder(strings.NewReader(jsonStr))
    var p3 Person
    decoder.Decode(&p3)
    fmt.Println(p3)
}

7.4 时间处理

package main

import (
    "fmt"
    "time"
)

func main() {
    // 当前时间
    now := time.Now()
    fmt.Println(now)

    // 创建时间
    t := time.Date(2024, 1, 15, 10, 30, 0, 0, time.Local)
    fmt.Println(t)

    // 格式化
    fmt.Println(now.Format("2006-01-02 15:04:05"))
    fmt.Println(now.Format("2006年01月02日"))

    // 解析
    t2, _ := time.Parse("2006-01-02", "2024-01-15")
    fmt.Println(t2)

    // 时间运算
    tomorrow := now.Add(24 * time.Hour)
    yesterday := now.AddDate(0, 0, -1)
    fmt.Println(tomorrow, yesterday)

    // 时间差
    duration := tomorrow.Sub(now)
    fmt.Println(duration.Hours())

    // 时间比较
    fmt.Println(now.Before(tomorrow))
    fmt.Println(now.After(yesterday))

    // 计时器
    start := time.Now()
    time.Sleep(100 * time.Millisecond)
    elapsed := time.Since(start)
    fmt.Println(elapsed)

    // Ticker
    ticker := time.NewTicker(1 * time.Second)
    go func() {
        for t := range ticker.C {
            fmt.Println("Tick at", t)
        }
    }()
    time.Sleep(3 * time.Second)
    ticker.Stop()
}

7.5 日志

package main

import (
    "log"
    "os"
)

func main() {
    // 基本日志
    log.Println("这是一条日志")
    log.Printf("格式化日志: %s", "test")
    log.Fatal("致命错误")  // 会退出程序
    log.Panic("恐慌错误")  // 会 panic

    // 自定义日志
    file, _ := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
    logger := log.New(file, "APP: ", log.LstdFlags|log.Lshortfile)
    logger.Println("写入文件的日志")

    // 日志标志
    logger.SetFlags(log.LstdFlags | log.Lshortfile)
    /*
    Ldate          日期: 2009/01/23
    Ltime          时间: 01:23:23
    Lmicroseconds  微秒: 01:23:23.123123
    Llongfile      完整文件名和行号
    Lshortfile     短文件名和行号
    Lmsgprefix     前缀移到消息前
    LstdFlags      标准格式 (Ldate | Ltime)
    */
}

小结

  1. os 包提供文件操作功能
  2. net/http 包提供 HTTP 客户端和服务器
  3. encoding/json 处理 JSON 数据
  4. time 包处理时间和日期
  5. log 包提供基本日志功能

参考资料