当前位置: 首页 > 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 停止服务器

相关文章:

  • 如何用AI生成个人职业照/西装照?
  • SALOME源码分析: SMESH模块
  • 17、商品管理:魔药商店运营——React 19 CRUD实现
  • React 后台管理系统
  • 涨薪技术|0到1学会性能测试第43课-apache status模块监控
  • SPL 量化 回测
  • 论文阅读:2024 arxiv Jailbreaking Black Box Large Language Models in Twenty Queries
  • python合并word中的run
  • Ubuntu ZLMediakit的标准配置文件(rtsp->rtmp->hls)
  • 《分词算法大揭秘:BPE、BBPE、WordPiece、ULM常见方法介绍》
  • 在原生代码(非webpack)里使用iview的注意事项
  • 回归分析丨基于R语言复杂数据回归与混合效应模型【多水平/分层/嵌套】技术与代码
  • AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年4月30日第68弹
  • mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz的下载安装和使用
  • PostgreSQL Patroni集群组件作用介绍:Patroni、etcd、HAProxy、Keepalived、Watchdog
  • 在Carla中构建自动驾驶:使用PID控制和ROS2进行路径跟踪
  • Android学习总结之自定义view设计模式理解
  • 尼日利亚slot游戏出海赛道借助本土网盟cpi流量广告投放优势
  • 企业数据合规实战:用API+AI构建备案核验系统
  • Python爬虫(11)Python数据存储实战:深入解析NoSQL数据库的核心应用与实战
  • 人民日报评论员:焕发风雨无阻、奋勇前行的精气神
  • 马上评丨准入壁垒越少,市场活力越足
  • 运动健康|不同能力跑者,跑步前后营养补给差别这么大?
  • 中国空间站首批在轨繁育果蝇即将返回地球,有望获得多项科学成果
  • 深入贯彻中央八项规定精神学习教育中央指导组培训会议召开
  • 比熬夜更伤肝的事,你可能每天都在做