[web] Golang中不创建文件的实现方法与问题探讨
[web] Golang中不创建文件的实现方法与问题探讨 我有这段代码,任务是上传文件。当我点击上传按钮时,文件没有在tmp目录中创建,我手动创建了目录,仅在本地机器上进行了测试。有什么想法吗?
package main
import (
"fmt"
"html/template"
"io"
"log"
"net/http"
"os"
)
const (
CONN_HOST = "localhost"
CONN_PORT = "8089"
)
func fileHandler(w http.ResponseWriter, r *http.Request) {
file, header, err := r.FormFile("file")
if err != nil {
log.Printf("error getting a file for the provided form key : ", err)
return
}
defer file.Close()
out, pathError := os.Create("/tmp/uploadedFile")
if pathError != nil {
log.Printf("error creating a file for writing : ", pathError)
return
}
defer out.Close()
_, copyFileError := io.Copy(out, file)
if copyFileError != nil {
log.Printf("error occurred while file copy : ", copyFileError)
}
fmt.Fprintf(w, "File uploaded successfully : "+header.Filename)
}
func index(w http.ResponseWriter, r *http.Request) {
parsedTemplate, _ := template.ParseFiles("templates/upload-file.html")
parsedTemplate.Execute(w, nil)
}
func main() {
http.HandleFunc("/", index)
http.HandleFunc("/upload", fileHandler)
err := http.ListenAndServe(CONN_HOST+":"+CONN_PORT, nil)
if err != nil {
log.Fatal("error starting http server : ", err)
return
}
}
更多关于[web] Golang中不创建文件的实现方法与问题探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html
3 回复
现在可以正常工作了,谢谢!
更多关于[web] Golang中不创建文件的实现方法与问题探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
您的代码可以完美地将文件上传到 /tmp 目录中
您可以通过以下修改来检查代码
out, pathError := os.Create("/tmp/uploadedFile")
改为
currDir, _ := os.Getwd() // 获取当前目录路径
out, pathError := os.Create(currDir + "/" + header.Filename)
在你的代码中,文件上传功能没有在/tmp目录创建文件,可能有几个原因。以下是具体分析和修改建议:
问题分析
- 硬编码的文件路径:
os.Create("/tmp/uploadedFile")总是创建同名文件,会覆盖之前的文件 - 缺少表单解析:需要在获取文件前调用
r.ParseMultipartForm() - 权限问题:可能没有在
/tmp目录的写入权限 - 文件命名:应该使用上传文件的原始名称
修正后的代码
package main
import (
"fmt"
"html/template"
"io"
"log"
"net/http"
"os"
"path/filepath"
)
const (
CONN_HOST = "localhost"
CONN_PORT = "8089"
UPLOAD_DIR = "./uploads" // 使用相对路径,避免权限问题
)
func fileHandler(w http.ResponseWriter, r *http.Request) {
// 解析表单,限制上传大小为10MB
err := r.ParseMultipartForm(10 << 20)
if err != nil {
log.Printf("Error parsing multipart form: %v", err)
http.Error(w, "Error parsing form", http.StatusBadRequest)
return
}
// 获取上传的文件
file, header, err := r.FormFile("file")
if err != nil {
log.Printf("Error getting file from form: %v", err)
http.Error(w, "Error retrieving file", http.StatusBadRequest)
return
}
defer file.Close()
// 创建上传目录(如果不存在)
if err := os.MkdirAll(UPLOAD_DIR, 0755); err != nil {
log.Printf("Error creating upload directory: %v", err)
http.Error(w, "Error creating directory", http.StatusInternalServerError)
return
}
// 使用原始文件名创建文件
filePath := filepath.Join(UPLOAD_DIR, header.Filename)
out, err := os.Create(filePath)
if err != nil {
log.Printf("Error creating file: %v", err)
http.Error(w, "Error creating file", http.StatusInternalServerError)
return
}
defer out.Close()
// 复制文件内容
_, err = io.Copy(out, file)
if err != nil {
log.Printf("Error copying file: %v", err)
http.Error(w, "Error saving file", http.StatusInternalServerError)
return
}
fmt.Fprintf(w, "File uploaded successfully: %s", header.Filename)
log.Printf("File saved to: %s", filePath)
}
func index(w http.ResponseWriter, r *http.Request) {
parsedTemplate, err := template.ParseFiles("templates/upload-file.html")
if err != nil {
http.Error(w, "Error loading template", http.StatusInternalServerError)
return
}
parsedTemplate.Execute(w, nil)
}
func main() {
http.HandleFunc("/", index)
http.HandleFunc("/upload", fileHandler)
log.Printf("Server starting on %s:%s", CONN_HOST, CONN_PORT)
err := http.ListenAndServe(CONN_HOST+":"+CONN_PORT, nil)
if err != nil {
log.Fatal("Error starting http server: ", err)
}
}
关键修改点
- 添加表单解析:
r.ParseMultipartForm(10 << 20)解析表单并限制上传大小 - 使用相对路径:改为
./uploads目录,避免系统目录权限问题 - 动态创建目录:
os.MkdirAll()确保上传目录存在 - 保留原始文件名:使用
header.Filename作为保存的文件名 - 改进错误处理:添加了适当的HTTP错误响应
对应的HTML模板示例
确保你的 templates/upload-file.html 包含正确的表单:
<!DOCTYPE html>
<html>
<head>
<title>File Upload</title>
</head>
<body>
<h2>Upload File</h2>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" required>
<input type="submit" value="Upload">
</form>
</body>
</html>
这些修改应该能解决文件创建的问题。主要问题很可能是缺少 r.ParseMultipartForm() 调用和系统目录的权限限制。

