1、SharpCifs的安装引用
使用Nuget管理工具搜索"SharpCifs"=>找到选择 "安装"
相关文档:VS(Visual Studio)中Nuget的使用
代码地址:https://github.com/zinkpad/SharpCifs
2、获取共享目录中路径和文件的方法
对于大量文件操作,可以考虑使用异步方式或批量操作来提高性能。确保应用程序具有访问 SMB 共享的权限。
//using System; //using SharpCifs.Smb; //获取文件夹的SmbFile-Object var folder = new SmbFile("smb://UserName:Password@ServerIP/ShareName/FolderName/"); //UnixTime var epocDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); //列出 items foreach (SmbFile item in folder.ListFiles()) { var lastModDate = epocDate.AddMilliseconds(item.LastModified()) .ToLocalTime(); var name = item.GetName(); var type = item.IsDirectory() ? "dir" : "file"; var date = lastModDate.ToString("yyyy-MM-dd HH:mm:ss"); var msg = $"{name} ({type}) - LastMod: {date}"; Console.WriteLine(msg); }
3、连接共享目录和验证帐户密码
将用户名和密码硬编码在代码中是不安全的。建议使用配置文件或环境变量来存储凭据。确保 SMB 服务器的安全性,例如启用 SMB 签名和数据加密。大文件传输时,考虑使用缓冲区来提高性能。
//using System; //using SharpCifs.Smb; //设置本地udp广播端口。 //连接时使用主机名, //将默认本地端口(137)更改为大于1024的值。 //在许多情况下,使用这个著名的港口是受到限制的。 // // **如果可能,使用IP地址而不是主机名 // **获得更好的性能。 // SharpCifs.Config.SetProperty("jcifs.smb.client.lport", "8137"); //string to Auth-Object. var auth1 = new NtlmPasswordAuthentication("UserName:Password"); var smb1 = new SmbFile("smb://192.168.0.1/ShareName/FolderName/", auth1); Console.WriteLine($"exists? {smb1.Exists()}"); //3 string to Auth-Object. var auth2 = new NtlmPasswordAuthentication(null, "UserName", "Password"); var smb2 = new SmbFile("smb://HostName/ShareName/FolderName/", auth2); Console.WriteLine($"exists? {smb2.Exists()}"); //插入用户密码到URL中. var smb3 = new SmbFile("smb://UserName:Password@HostName/ShareName/FolderName/"); Console.WriteLine($"exists? {smb3.Exists()}"); //您可以将身份验证信息存储在SharpCifs.Std中。 SharpCifs.Config.SetProperty("jcifs.smb.client.username", "UserName"); SharpCifs.Config.SetProperty("jcifs.smb.client.password", "Password"); var smb4 = new SmbFile("smb://HostName/ShareName/FolderName/"); Console.WriteLine($"exists? {smb4.Exists()}");
4、从共享目录中读取文件
确保共享路径正确,提供正确的域名、用户名和密码。添加异常处理来捕获潜在的错误,例如网络连接失败、权限不足等。
//using System; //using System.IO; //using System.Text; //using SharpCifs.Smb; //获取目录的SmbFile. var file = new SmbFile("smb://UserName:Password@ServerIP/ShareName/Folder/FileName.txt"); //获取可读的流。 var readStream = file.GetInputStream(); //创建读取缓存 var memStream = new MemoryStream(); //获取 bytes. ((Stream)readStream).CopyTo(memStream); //Dispose可读的流。 readStream.Dispose(); Console.WriteLine(Encoding.UTF8.GetString(memStream.ToArray()));
5、在共享目录中创建新文件
确保账户在共享目录上具有足够的写入权限,文件路径应该相对于共享目录的根目录。对于大量文件操作,可以考虑使用异步方式或批量操作来提高性能。
//using System.Text; //using SharpCifs.Smb; //获取指定要创建的文件名的SmbFile。 var file = new SmbFile("smb://UserName:Password@ServerIP/ShareName/Folder/NewFileName.txt"); //创建文件 file.CreateNewFile(); //获取可写的stream. var writeStream = file.GetOutputStream(); //写入 bytes内容. writeStream.Write(Encoding.UTF8.GetBytes("Hello!")); //Dispose 可写的 stream. writeStream.Dispose();
6、浏览在局域网中的共享服务
用户需要有足够的权限访问共享目录,对于网络错误或文件操作异常,应进行适当的异常处理。设置本地udp广播端口。连接时使用主机名,将默认本地端口(8137)更改为大于1024
的值。在许多情况下,使用这个端口是受到限制的。如果可能,使用IP地址而不是主机名,会有获得更好的性能。
//using System; //using SharpCifs.Smb; SharpCifs.Config.SetProperty("jcifs.smb.client.lport", "8137"); //得到本地的工作组 var lan = new SmbFile("smb://", ""); var workgroups = lan.ListFiles(); foreach (var workgroup in workgroups) { Console.WriteLine($"Workgroup Name = {workgroup.GetName()}"); try { //Get servers in workgroup. var servers = workgroup.ListFiles(); foreach (var server in servers) { Console.WriteLine($"{workgroup.GetName()} - Server Name = {server.GetName()}"); try { //Get shared folders in server. var shares = server.ListFiles(); foreach (var share in shares) { Console.WriteLine($"{workgroup.GetName()}{server.GetName()} - Share Name = {share.GetName()}"); } } catch (Exception) { Console.WriteLine($"{workgroup.GetName()}{server.GetName()} - Access Denied"); } } } catch (Exception) { Console.WriteLine($"{workgroup.GetName()} - Access Denied"); } }
7、主机名称解析
确保防火墙允许 SMB 访问,确保提供的用户名和密码具有正确的权限。
//using System; //using System.Net; //using SharpCifs.Netbios; //设置本地udp广播端口。 //连接时使用主机名, //将默认本地端口(137)更改为大于1024的值。 //在许多情况下,使用这个著名的港口是受到限制的。 // // **如果可能,使用IP地址而不是主机名 // **获得更好的性能。 // SharpCifs.Config.SetProperty("jcifs.smb.client.lport", "8137"); var naddr = NbtAddress.GetByName("HostName"); IPAddress addr = naddr.GetInetAddress(); Console.WriteLine($"IP = {addr}");
8、设置共享参数
SharpCifs 提供了丰富的配置选项,可以根据需要进行调整,如超时设置、代理设置等。
//设置本地IP地址。
//如果发生连接错误(例如:连接失败:[NET BIOS NAME]),
//尝试设置本地IP地址。
//当设备的主机名作为DNS名称无效时,
//要确定当地的地址可能是不可能的。
SharpCifs.Config.SetProperty("jcifs.smb.client.laddr", "192.168.0.2");
//设置本地udp广播端口。
//连接时使用主机名,
//将默认本地端口(137)更改为大于1024的值。
//在许多情况下,使用这个著名的港口是受到限制的。
//
// **如果可能,使用IP地址而不是主机名
// **获得更好的性能。
//
SharpCifs.Config.SetProperty("jcifs.smb.client.lport", "8137");
//您可以将身份验证信息存储在SharpCifs.Std中。
SharpCifs.Config.SetProperty("jcifs.smb.client.username", "UserName");
SharpCifs.Config.SetProperty("jcifs.smb.client.password", "Password");
//如果您不使用DFS(分布式文件系统),
//禁用DFS可以提高NetBios名称解析的速度。
SharpCifs.Config.SetProperty("jcifs.smb.client.dfs.disabled", "true");
//更多的配置参数在JCIFS官方站点中。
//https://jcifs.samba.org/src/docs/api/overview-summary.html
9、刷新设置和连接缓存
使用 SMB 协议访问共享文件夹时,本地操作系统通常会缓存文件和目录信息,以提高访问速度。但是,缓存也可能导致数据不一致的问题,尤其是在文件频繁更新的情况下。操作系统会缓存 SMB 连接信息,以便下次访问时可以快速建立连接。
//---------------------------------------- //必选:版本0.2.9或更高。 //---------------------------------------- // //强制应用设置值。 //在默认操作上,应用第一次smb处理时的设置值,并且不能更改。 //该方法强制应用SMB处理后更改的设置值。 // //并且,这个方法处理当前无效的缓存连接。 //例如,在连接后30分钟内不能工作的连接将被处理。 SmbFile.Initialize(); //重置无效的连接。 //使用此方法处理无效连接,而无需操作设置值。 SmbTransport.ClearCachedConnections(); //重置所有(包括活动)连接。 //使用此方法处理所有连接,包括当前连接。 //注意,即使在数据传输期间,它也会处理连接。 SmbTransport.ClearCachedConnections(true);