当前位置: 首页 > news >正文

Golang - 实现文件管理服务器

先看效果:

代码如下:

package mainimport ("fmt""html/template""log""net/http""os""path/filepath""strings"
)// 配置根目录(根据需求修改)
//var baseDir = filepath.Join(os.Getenv("/")) // 用户主目录
// var baseDir = "C:\\" // Windows系统使用C盘根目录
var baseDir = "/"    // Linux/Mac使用系统根目录// 文件信息结构体
type FileInfo struct {Name  stringPath  stringIsDir bool
}// 页面数据
type PageData struct {Path      stringParentDir stringFiles     []FileInfo
}// 自定义模板函数
var templateFuncs = template.FuncMap{"splitPath": func(path string) []string {return strings.Split(path, string(filepath.Separator))},"joinPath": func(parts ...string) string {return filepath.Join(parts...)},"slicePath": func(path string, index int) string {parts := strings.Split(path, string(filepath.Separator))return filepath.Join(parts[:index]...)},
}func main() {// 设置路由http.HandleFunc("/", fileHandler)// 启动服务器fmt.Printf("文件管理服务器已启动,访问 http://localhost:8000/\n")fmt.Printf("根目录: %s\n", baseDir)fmt.Println("按 Ctrl+C 停止服务器")log.Fatal(http.ListenAndServe(":8000", nil))
}func fileHandler(w http.ResponseWriter, r *http.Request) {// 获取路径参数path := r.URL.Query().Get("path")fullPath := filepath.Join(baseDir, path)// 安全检查:确保路径在baseDir下if !strings.HasPrefix(filepath.Clean(fullPath), filepath.Clean(baseDir)) {http.Error(w, "禁止访问", http.StatusForbidden)return}// 检查路径是否存在fileInfo, err := os.Stat(fullPath)if err != nil {if os.IsNotExist(err) {http.Error(w, "文件不存在", http.StatusNotFound)} else {http.Error(w, "无法访问文件", http.StatusInternalServerError)}return}// 如果是文件,直接提供下载if !fileInfo.IsDir() {http.ServeFile(w, r, fullPath)return}// 如果是目录,列出内容dirEntries, err := os.ReadDir(fullPath)if err != nil {http.Error(w, "无法读取目录", http.StatusInternalServerError)return}// 准备文件列表var files []FileInfo// 添加上级目录链接(如果不是根目录)if path != "" {parentDir := filepath.Dir(path)if parentDir == path {parentDir = ""}files = append(files, FileInfo{Name:  ".. (上级目录)",Path:  parentDir,IsDir: true,})}// 添加目录和文件for _, entry := range dirEntries {entryPath := filepath.Join(path, entry.Name())files = append(files, FileInfo{Name:  entry.Name(),Path:  entryPath,IsDir: entry.IsDir(),})}// 准备模板数据data := PageData{Path:      path,ParentDir: filepath.Dir(path),Files:     files,}// 创建带有自定义函数的模板tmpl := template.New("filelist").Funcs(templateFuncs)// 解析模板tmpl, err = tmpl.Parse(htmlTemplate)if err != nil {http.Error(w, "模板错误: "+err.Error(), http.StatusInternalServerError)return}// 执行模板err = tmpl.Execute(w, data)if err != nil {http.Error(w, "模板渲染错误: "+err.Error(), http.StatusInternalServerError)}
}// HTML模板(移除了非ASCII字符)
const htmlTemplate = `
<!DOCTYPE html>
<html>
<head><title>文件管理器 - {{.Path}}</title><style>body { font-family: Arial, sans-serif; margin: 20px; }h1 { color: #333; }ul { list-style-type: none; padding: 0; }li { padding: 5px 0; }a { text-decoration: none; color: #0066cc; }a:hover { text-decoration: underline; }.file { color: #666; }.dir { color: #009933; font-weight: bold; }.breadcrumb { margin-bottom: 20px; }</style>
</head>
<body><h1>文件管理器</h1><div class="breadcrumb"><a href="/?path=">根目录</a>{{if .Path}}{{range $i, $part := splitPath .Path}}/ <a href="/?path={{joinPath (slicePath $.Path $i) $part}}">{{$part}}</a>{{end}}{{end}}</div><ul>{{range .Files}}<li><a href="/?path={{.Path}}" class="{{if .IsDir}}dir{{else}}file{{end}}">{{if .IsDir}}[DIR]{{else}}[FILE]{{end}} {{.Name}}</a></li>{{end}}</ul>
</body>
</html>
`

启动服务:

[root@localhost test]# go run file.go
文件管理服务器已启动,访问 http://localhost:8000/
根目录: /
按 Ctrl+C 停止服务器

http://www.xdnf.cn/news/224569.html

相关文章:

  • scGPT方法解读
  • 突发-2小时前DeepSeek发布了新模型-不是R2
  • 中小企业如何借助智能海关系统降低跨境运输成本?
  • day006-实战练习题-参考答案
  • 基于 IAR Embedded Workbench 的自研 MCU 芯片软件函数与变量内存布局优化精控方法
  • LeetCode 2905 找出满足差值条件的下标II 题解
  • AI驱动的决策智能系统(AIDP)和自然语言交互式分析
  • ArcGIS+GPT:多领域地理分析与决策新方案
  • 第十一节:Shell脚本编程
  • 软件架构选型之“如何选”
  • Walrus 与 Pudgy Penguins 达成合作,为 Web3 头部 IP 引入去中心化存储
  • 米壳AI:跨境电商图片翻译的“隐形革命”:当AI技术遇上全球化生意
  • Azure Monitor 实战指南:全方位监控应用与基础设施
  • 零基础学指针2
  • 蓝桥杯赛后总结
  • Transformer:颠覆深度学习的架构革命与技术演进
  • HTTP/HTTPS
  • shell(5)
  • 2025年真实面试问题汇总(一)
  • MCP协议:自然语言与结构化数据的双向桥梁 ——基于JSON-RPC 2.0的标准化实践
  • 备战2025年全国信息素养大赛图形化挑战赛——判断闰年和平年
  • iOS RunLoop 深入解析
  • Linux:network: mtu: 隐形知识frag_max_size
  • webpack5启动项目报错:process is not defined
  • CSS常用属性_(进阶)
  • 理解数据库存储以及查询(集合)
  • 强化学习_Paper_2017_Curiosity-driven Exploration by Self-supervised Prediction
  • ROS2与Carla安装设备指南(其二)
  • K8S Secret 快速开始
  • ArrayList的特点及应用场景