C# .NET Core运行在Linux环境下如何获取网络路径中的文件
问题原因
这是跨平台SMB共享访问的原生机制差异导致的:
- Windows内核原生支持UNC路径(
\\servername\foldername)的直接解析,会自动处理SMB协议交互,所以.NET的IO方法可以直接读取该路径 - Linux没有内置路径层面的SMB解析能力,.NET运行在Linux环境时,会将
//servername/foldername当做普通本地路径处理,不会自动发起SMB连接请求,所以直接调用会抛出路径不存在的错误
解决方法
方法一:预先挂载SMB共享到本地目录(生产环境推荐,稳定性最高)
不需要修改核心业务逻辑,只需要调整系统配置和代码路径即可:
- 安装SMB挂载工具,不同发行版安装命令:
- Debian/Ubuntu系列:
sudo apt install cifs-utils - CentOS/RHEL系列:
sudo yum install cifs-utils
- Debian/Ubuntu系列:
- 创建本地挂载目录,例如:
sudo mkdir /mnt/smb_share - 执行临时挂载命令,替换对应配置项即可:
如果需要开机自动挂载,将下面配置添加到sudo mount -t cifs //servername/foldername /mnt/smb_share -o username=SMB账号,password=SMB密码,uid=运行.NET程序的用户ID,gid=运行.NET程序的用户组ID/etc/fstab文件中:
其中//servername/foldername /mnt/smb_share cifs credentials=/etc/smb_creds,uid=1000,gid=1000 0 0/etc/smb_creds用于存储SMB账号密码,避免明文泄露,文件内容格式为:
配置完成后执行username=你的SMB账号 password=你的SMB密码sudo chmod 600 /etc/smb_creds设置文件权限即可。 - 挂载成功后,修改代码路径为本地挂载目录即可正常运行:
var filePaths = Directory.GetFiles("/mnt/smb_share");
方法二:代码集成SMB客户端直接访问(无系统依赖)
如果不方便修改服务器配置,可以直接在代码中集成SMB协议库实现访问,常用的第三方库为SMBLibrary,使用示例如下:
- 先通过NuGet安装
SMBLibrary包 - 代码示例:
该方案不需要依赖服务器配置,跨平台兼容性更好,适合需要灵活访问多个SMB共享的场景。using SMBLibrary; using SMBLibrary.Client; // 建立SMB连接 var client = new SMB2Client(); bool connectSuccess = client.Connect(System.Net.IPAddress.Parse("服务器IP"), SMBTransportType.DirectTCPTransport); if (connectSuccess) { // 登录SMB服务 NTStatus loginStatus = client.Login(string.Empty, "SMB账号", "SMB密码"); if (loginStatus == NTStatus.STATUS_SUCCESS) { // 连接目标共享目录 ISMBFileStore fileStore = client.TreeConnect("foldername", out NTStatus connectStatus); if (connectStatus == NTStatus.STATUS_SUCCESS) { // 列举目录下所有文件 NTStatus queryStatus = fileStore.QueryDirectory(out List<QueryDirectoryFileInformation> fileList, @"*", FileInformationClass.FileDirectoryInformation); if (queryStatus == NTStatus.STATUS_SUCCESS) { foreach (var file in fileList) { // 自定义文件处理逻辑 } } fileStore.Disconnect(); } } client.Disconnect(); }
内容的提问来源于stack exchange,提问作者user1472131
相关产品推荐
相关产品推荐

