用一个命令让 OpenCode 帮你从零写一个静态文件服务器。功能:指定端口启动 HTTP 服务,浏览器访问即可浏览/下载当前目录下的文件。技术栈:Go 标准库,零依赖。
opencode init 初始化过项目)mkdir go-fileserver && cd go-fileserver go mod init fileserver
我对 OpenCode 说:
用 Go 写一个 HTTP 文件服务器 main.go,功能: 1. 命令行参数接收端口号,默认 8080 2. 把当前目录作为根目录提供文件浏览和下载 3. 自动生成目录列表页面(含文件大小和修改时间) 4. 启动时打印访问地址
OpenCode 扫描了项目结构,几秒内生成了以下代码:
package main
import (
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"path/filepath"
"strings"
"text/html"
)
func main() {
port := flag.Int("p", 8080, "监听端口")
flag.Parse()
dir, _ := os.Getwd()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
serveFile(w, r, dir)
})
addr := fmt.Sprintf(":%d", *port)
fmt.Printf("📁 文件服务器已启动\n")
fmt.Printf(" 本地: http://localhost%s\n", addr)
if ip := getLocalIP(); ip != "" {
fmt.Printf(" 局域网: http://%s%s\n", ip, addr)
}
log.Fatal(http.ListenAndServe(addr, nil))
}
func serveFile(w http.ResponseWriter, r *http.Request, root string) {
path := filepath.Join(root, filepath.Clean(r.URL.Path))
info, err := os.Stat(path)
if err != nil {
http.NotFound(w, r)
return
}
if info.IsDir() {
entries, _ := os.ReadDir(path)
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprintf(w, `<html><head><meta charset="utf-8"><title>%s</title>
<style>body{font-family:monospace;max-width:800px;margin:20px auto}
a{text-decoration:none;color:#06c}tr:hover{background:#f5f5f5}
td{padding:6px 12px}</style></head><body>
<h2>📂 %s</h2><table>`, r.URL.Path, r.URL.Path)
for _, e := range entries {
name := e.Name()
if strings.HasPrefix(name, ".") {
continue
}
info, _ := e.Info()
size := formatSize(info.Size())
modTime := info.ModTime().Format("2006-01-02 15:04")
link := filepath.Join(r.URL.Path, name)
icon := "📄"
if e.IsDir() {
icon = "📁"
link += "/"
}
fmt.Fprintf(w, `<tr><td>%s</td><td><a href="%s">%s</a></td>
<td>%s</td><td>%s</td></tr>`, icon, link, html.EscapeString(name), size, modTime)
}
fmt.Fprint(w, `</table></body></html>`)
return
}
http.ServeFile(w, r, path)
}
func formatSize(size int64) string {
units := []string{"B", "KB", "MB", "GB"}
s := float64(size)
i := 0
for s >= 1024 && i < len(units)-1 {
s /= 1024
i++
}
return fmt.Sprintf("%.1f %s", s, units[i])
}
func getLocalIP() string {
addrs, _ := net.InterfaceAddrs()
for _, addr := range addrs {
if ip, ok := addr.(*net.IPNet); ok && !ip.IP.IsLoopback() && ip.IP.To4() != nil {
return ip.IP.String()
}
}
return ""
}
我对 OpenCode 说:
运行这个服务,验证能否正常访问
OpenCode 执行:
go run main.go -p 9090
输出:
📁 文件服务器已启动 本地: http://localhost:9090 局域网: http://192.168.1.5:9090
浏览器打开 http://localhost:9090,完美显示目录列表,点击文件即可下载。
上面那段就是全部代码,共 95 行。零外部依赖,纯 Go 标准库实现。
| 对比项 | 手写 | 用 OpenCode |
|--------|------|------------|
| 编码时间 | ~20 分钟 | ~1 分钟 |
| 描述需求 | 自己思考 | 自然语言说完 |
| 调试修正 | 5-10 分钟 | 0(一次通过) |
全程我只说了两句话:一句描述需求,一句让运行。代码质量——自动隐藏 . 开头的文件、响应式表格样式、局域网 IP 检测——这些细节我甚至没在需求里提,OpenCode 自己做了合理推断。
这就是 OpenCode 实践课想传递的核心:把时间花在说清楚要什么,而不是怎么写。