You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Java、Python或Linux CLI获取SMB共享文件名称与权限?

我来帮你梳理几个可行的方案,针对你需要的SMB文件浏览+权限获取、全dialect支持的需求,分别从Java、Python和Java可调用的Linux CLI三个方向给出实现思路:

Java 实现方案(基于 smbj 优化)

你之前尝试过smbj,但可能没找到正确获取权限的方式——其实smbj完全支持获取文件/文件夹的权限信息,并且可以配置兼容所有SMB dialects。这里给你调整后的代码逻辑:

首先确保引入依赖(以Maven为例):

<dependency>
    <groupId>com.hierynomus</groupId>
    <artifactId>smbj</artifactId>
    <version>0.11.6</version>
</dependency>

核心实现代码:

import com.hierynomus.msfscc.fileinformation.FileIdBothDirectoryInformation;
import com.hierynomus.mssmb2.*;
import com.hierynomus.smbj.SMBClient;
import com.hierynomus.smbj.auth.AuthenticationContext;
import com.hierynomus.smbj.connection.Connection;
import com.hierynomus.smbj.session.Session;
import com.hierynomus.smbj.share.DiskShare;

import java.util.List;

public class SmbFileBrowser {
    public static void main(String[] args) throws Exception {
        // 配置支持所有SMB dialects(覆盖SMB2到SMB3全版本)
        SMBClient client = new SMBClient(config -> {
            config.setDialects(SMBDialect.SMB2_0_2, SMBDialect.SMB2_1, SMBDialect.SMB3_0, SMBDialect.SMB3_0_2, SMBDialect.SMB3_1_1);
            return config;
        });

        // 替换为你的服务器信息
        String serverName = "your-server-ip";
        int port = 445;
        String username = "your-username";
        String password = "your-password";
        String shareName = "your-share-name";
        String targetPath = "your-target-folder-path";

        try (Connection connection = client.connect(serverName, port)) {
            AuthenticationContext auth = new AuthenticationContext(username, password.toCharArray(), null);
            Session session = connection.authenticate(auth);

            // 连接目标共享
            try (DiskShare share = (DiskShare) session.connectShare(shareName)) {
                // 遍历指定路径下的所有文件/文件夹
                List<FileIdBothDirectoryInformation> files = share.list(targetPath);
                for (FileIdBothDirectoryInformation file : files) {
                    if (file.getFileName().matches("\\.|\\.\\.")) continue; // 跳过当前/上级目录
                    String fileName = file.getFileName();
                    boolean isDirectory = file.isDirectory();

                    // 获取文件/文件夹的安全描述符,解析权限信息
                    SMB2SecurityDescriptor sd = share.getSecurityDescriptor(targetPath + "/" + fileName);
                    List<SMB2AccessControlEntry> permissions = sd.getDacl().getAces();

                    // 处理权限数据,这里示例为打印信息
                    System.out.println("名称: " + fileName + " (是否文件夹: " + isDirectory + ")");
                    for (SMB2AccessControlEntry ace : permissions) {
                        System.out.println("  权限主体SID: " + ace.getSid().toString());
                        System.out.println("  权限类型: " + (ace.getType() == SMB2AccessControlType.ACCESS_ALLOWED_ACE_TYPE ? "允许" : "拒绝"));
                        System.out.println("  权限掩码: " + ace.getMask());
                    }
                }
            }
        }
    }
}
Python 实现方案(基于 impacket 优化)

你之前用impacket没满足需求,大概率是没正确解析权限信息。impacket的SMBConnection可以直接获取文件的安全描述符,进而提取权限:

from impacket.smbconnection import SMBConnection

def smb_browse_with_perms(server_ip, username, password, share_name, target_path):
    # 建立SMB连接
    conn = SMBConnection(server_ip, server_ip, sess_port=445)
    conn.login(username, password)

    # 连接目标共享
    conn.connectTree(share_name)

    # 遍历指定路径下的文件/文件夹
    file_list = conn.listPath(share_name, f"{target_path}\\*")
    for file in file_list:
        if file.get_longname() in ['.', '..']:
            continue
        file_name = file.get_longname()
        is_directory = file.is_directory()

        # 获取文件安全描述符,解析权限
        sec_desc = conn.getSecurityDescriptor(share_name, f"{target_path}\\{file_name}")
        print(f"名称: {file_name} (是否文件夹: {is_directory})")
        
        dacl = sec_desc.get('Dacl')
        if dacl:
            for ace in dacl['Ace']:
                print(f"  权限主体: {ace['Sid'].formatCanonical()}")
                print(f"  权限类型: {'允许' if ace['AceType'] == 0 else '拒绝'}")
                print(f"  权限掩码: {ace['AceFlags']}")

    # 关闭连接
    conn.close()

# 调用示例
smb_browse_with_perms("your-server-ip", "your-username", "your-password", "your-share-name", "your-target-path")
Java 可调用的 Linux CLI 方案

如果偏好通过CLI工具快速实现,Java可以通过ProcessBuilder调用Samba套件的smbclient或rpcclient工具,解析输出获取权限:

用 smbclient 获取文件列表和权限

命令示例(直接在终端执行):

smbclient //your-server-ip/your-share-name -U your-username%your-password -c "ls your-target-path; getfacl your-target-path/*"

Java调用代码:

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class SmbCliInvoker {
    public static void main(String[] args) throws Exception {
        // 替换为你的配置信息
        String serverIp = "your-server-ip";
        String shareName = "your-share-name";
        String username = "your-username";
        String password = "your-password";
        String targetPath = "your-target-path";

        // 构建smbclient命令
        ProcessBuilder pb = new ProcessBuilder(
            "smbclient",
            "//" + serverIp + "/" + shareName,
            "-U", username + "%" + password,
            "-c", String.format("ls %s; getfacl %s/*", targetPath, targetPath)
        );

        // 执行命令并解析输出
        Process process = pb.start();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line = reader.readLine()) != null) {
            // 这里可以根据输出格式,提取文件名和权限信息
            System.out.println(line);
        }
        reader.close();
        process.waitFor();
    }
}

内容的提问来源于stack exchange,提问作者zuckermanori

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:30:36