在Go语言中读取Ubuntu挂载的Samba文件时提示‘文件或目录不存在’
解决Go语言读取SMB挂载文件时的"no such file or directory"错误
嘿,这个问题我之前帮人排查过好几次,原因很明确——ioutil.ReadFile(包括Go标准库中所有本地文件操作函数)只能识别本地文件系统的路径,你传入的smb://192.168.32.114/test/test.html是SMB网络协议的URL格式,标准库完全不认识它,所以才会抛出"找不到文件或目录"的错误。
给你两种靠谱的解决方案:
方案一:使用本地挂载路径读取(推荐,依赖系统挂载)
既然你的Ubuntu机器已经挂载了这个SMB共享,那它肯定对应着本地的一个挂载目录(比如/mnt/smb-test这类路径)。你只需要把代码里的SMB URL替换成这个本地路径就行:
package main import ( "io/ioutil" "log" ) func main() { // 替换成你实际的SMB共享本地挂载路径 localFilePath := `/mnt/smb-test/test.html` dat, err := ioutil.ReadFile(localFilePath) if err != nil { log.Println("读取失败:", err) return } log.Println("文件读取成功,内容长度:", len(dat)) }
如果还没确认挂载路径,你可以在Ubuntu终端执行df -h命令,找到对应//192.168.32.114/test的挂载点。另外要注意:运行Go程序的用户需要有这个挂载目录的读取权限,否则会遇到权限错误,可以用chmod 755 /mnt/smb-test调整权限,或者挂载时加上uid=你的用户ID参数。
方案二:用第三方SMB库直接读取(无需系统挂载)
如果不想依赖系统的SMB挂载,你可以用Go的第三方SMB客户端库直接通过协议读取文件,比如go-smb2:
首先安装依赖:
go get github.com/hirochachacha/go-smb2
然后编写代码:
package main import ( "io/ioutil" "log" "net" "github.com/hirochachacha/go-smb2" ) func main() { // 连接SMB服务器的445端口 conn, err := net.Dial("tcp", "192.168.32.114:445") if err != nil { log.Fatal("连接SMB服务器失败:", err) } defer conn.Close() // 初始化SMB会话(替换成你的SMB账号密码) dialer := &smb2.Dialer{ Initiator: &smb2.NTLMInitiator{ User: "your-smb-username", Password: "your-smb-password", }, } sess, err := dialer.Dial(conn) if err != nil { log.Fatal("创建SMB会话失败:", err) } defer sess.Close() // 挂载共享目录 share, err := sess.Mount("test") if err != nil { log.Fatal("挂载共享失败:", err) } defer share.Umount() // 打开并读取文件 file, err := share.Open("test.html") if err != nil { log.Fatal("打开文件失败:", err) } defer file.Close() dat, err := ioutil.ReadAll(file) if err != nil { log.Fatal("读取文件内容失败:", err) } log.Println("文件读取成功,内容长度:", len(dat)) }
两种方案各有优劣:方案一更简单,依赖系统的挂载管理;方案二更灵活,适合需要动态处理SMB共享的场景。
内容的提问来源于stack exchange,提问作者oldsport
相关产品推荐
相关产品推荐

