第七章:标准库
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)
*/
}
小结
- os 包提供文件操作功能
- net/http 包提供 HTTP 客户端和服务器
- encoding/json 处理 JSON 数据
- time 包处理时间和日期
- log 包提供基本日志功能
参考资料