Golang文件上传问题:io.Reader类型不是一个有效表达式
Golang文件上传问题:io.Reader类型不是一个有效表达式 我在使用 jlaffaye/ftp 上传现有文件到 FTP 时遇到了一些问题。没有直接的“上传”命令。我找到的最接近的是 StorFrom()。
ftp package - github.com/jlaffaye/ftp - Go Packages
Package ftp implements a FTP client as described in RFC 959.
但它的语法对我来说是个隐藏的秘密。我找不到任何关于如何使用它的示例。
package main
import (
"fmt"
"github.com/jlaffaye/ftp"
"io"
"os"
"time"
)
func send2ftp(filename string) {
c, err := ftp.Dial("ftp.test.com:21", ftp.DialWithTimeout(5*time.Second))
if err != nil {
fmt.Println(err)
}
err = c.Login("test", "test")
if err != nil {
fmt.Println(err)
}
if _, err := os.Stat(filename); err != nil {
if os.IsNotExist(err) {
fmt.Println("does not exist")
}
} else {
fmt.Println("exists")
}
err = c.StorFrom(filename, io.Reader, 0)
if err != nil {
panic(err)
}
}
https://play.golang.com/p/xPykHDRei-U
尝试寻找语法时出现了这个错误:
type io.Reader is not an expression
问题很简单:我如何将现有文件上传到 FTP?或者,如何使用一个字符串值在 FTP 上创建文件。
更多关于Golang文件上传问题:io.Reader类型不是一个有效表达式的实战教程也可以访问 https://www.itying.com/category-94-b0.html
(*ServerConn).StorFrom 期望接收一个实现了 io.Reader 接口的参数。如果你想从计算机上传文件,可以使用 os.Open 打开文件,然后将文件句柄传递给 StorFrom。完成后别忘了关闭文件!
更多关于Golang文件上传问题:io.Reader类型不是一个有效表达式的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
根据你的代码,主要问题在于StorFrom方法的第二个参数需要传入一个具体的io.Reader实例,而不是io.Reader类型本身。以下是修正后的代码示例:
package main
import (
"fmt"
"github.com/jlaffaye/ftp"
"os"
"time"
)
func send2ftp(filename string) {
// 建立FTP连接
c, err := ftp.Dial("ftp.test.com:21", ftp.DialWithTimeout(5*time.Second))
if err != nil {
fmt.Println(err)
return
}
defer c.Quit()
// 登录
err = c.Login("test", "test")
if err != nil {
fmt.Println(err)
return
}
// 检查文件是否存在
file, err := os.Open(filename)
if err != nil {
if os.IsNotExist(err) {
fmt.Println("文件不存在:", filename)
} else {
fmt.Println("打开文件失败:", err)
}
return
}
defer file.Close()
// 获取文件信息用于验证
fileInfo, err := file.Stat()
if err != nil {
fmt.Println("获取文件信息失败:", err)
return
}
fmt.Printf("文件存在,大小: %d bytes\n", fileInfo.Size())
// 上传文件 - 这里使用Stor方法更简单
err = c.Stor(filename, file)
if err != nil {
fmt.Println("上传失败:", err)
return
}
fmt.Println("上传成功")
}
// 如果确实需要使用StorFrom方法(支持断点续传),可以这样写:
func send2ftpWithStorFrom(filename string) {
c, err := ftp.Dial("ftp.test.com:21", ftp.DialWithTimeout(5*time.Second))
if err != nil {
fmt.Println(err)
return
}
defer c.Quit()
err = c.Login("test", "test")
if err != nil {
fmt.Println(err)
return
}
file, err := os.Open(filename)
if err != nil {
fmt.Println("打开文件失败:", err)
return
}
defer file.Close()
// StorFrom的第三个参数是偏移量(用于断点续传)
// 0表示从文件开始上传
err = c.StorFrom(filename, file, 0)
if err != nil {
fmt.Println("上传失败:", err)
return
}
fmt.Println("上传成功")
}
// 上传字符串内容到FTP文件
func uploadStringToFTP(filename, content string) error {
c, err := ftp.Dial("ftp.test.com:21", ftp.DialWithTimeout(5*time.Second))
if err != nil {
return err
}
defer c.Quit()
err = c.Login("test", "test")
if err != nil {
return err
}
// 将字符串转换为io.Reader
reader := strings.NewReader(content)
// 使用Stor方法上传
err = c.Stor(filename, reader)
if err != nil {
return err
}
return nil
}
func main() {
// 上传文件
send2ftp("example.txt")
// 或者上传字符串
// uploadStringToFTP("example.txt", "这是文件内容")
}
关键点:
io.Reader是一个接口类型,不能直接作为参数值传入,需要传入实现了该接口的具体实例os.Open()返回的*os.File已经实现了io.Reader接口- 对于字符串内容,可以使用
strings.NewReader()创建io.Reader - 对于简单的上传需求,使用
Stor方法比StorFrom更直接 StorFrom的第三个参数是偏移量,用于断点续传场景,从0开始表示完整上传

