您的位置:首页 >Go 如何扫描网络共享文件夹
发布于2026-03-12 阅读(0)
扫一扫,手机访问

Go 标准库不支持直接枚举 UNC 路径(如 `\\ComputerA`)下的共享文件夹,需借助系统命令(如 Windows 的 `net view`)并解析其输出来实现跨平台或目标平台的共享发现。
在 Go 中,os.ReadDir(或旧版 ioutil.ReadDir)仅能读取已知共享路径(如 \\ComputerA\Source)下的文件和子目录,但无法列出远程主机根级的共享名列表(即 \\ComputerA 本身)。这是因为 UNC 根路径 \\ComputerA 并非一个常规文件系统目录,而是一个 SMB 共享枚举入口——该操作需依赖底层操作系统提供的网络发现协议(如 SMB/CIFS 的 NetShareEnum),而 Go 标准库(os、net、io/fs 等)并未封装此类功能。
✅ 正确做法是调用宿主系统的原生命令:
以下是一个 Windows 平台的 Go 示例实现:
package main
import (
"fmt"
"os/exec"
"strings"
"syscall"
)
func listSharesOnWindows(host string) ([]string, error) {
cmd := exec.Command("net", "view", "\\\\"+host)
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
out, err := cmd.Output()
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok && exitErr.ExitCode() == 2 {
return nil, fmt.Errorf("computer '%s' not found or unreachable", host)
}
return nil, fmt.Errorf("failed to run 'net view': %w", err)
}
var shares []string
for _, line := range strings.Split(string(out), "\n") {
// 共享名通常位于行首,以字母/数字开头,后跟若干空格和描述
fields := strings.Fields(line)
if len(fields) >= 2 && strings.HasSuffix(fields[1], "Disk") {
shareName := fields[0]
// 过滤掉标题行(如 "Share name")和分隔线
if shareName != "Share" && shareName != "-------" {
shares = append(shares, shareName)
}
}
}
return shares, nil
}
func main() {
shares, err := listSharesOnWindows("ComputerA")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Found shares on ComputerA: %v\n", shares)
// 示例输出: Found shares on ComputerA: [Source Data Backup]
}⚠️ 注意事项:
总结:Go 本身不提供跨平台 SMB 共享发现能力,必须桥接系统工具。这是权衡简洁性与功能性的典型场景——用标准库处理「已知路径」,用 exec.Command 处理「服务发现」。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9