前言
在Microsoft 网 络 系 统 中,SMB(Server Message Block, 服 务 信 息 块) 协 议 是Windows for Workgroup(WfWg)、Windows 95、Windows NT 和LanManager 用 来 实 现 共 享 局 域 网 上 文 件 和 打 印 机 的 协 议。 对 于 利 用Linux 和Windows NT 构 建 的 局 域 网 来 说,Samba 就 是 为Linux 提 供 的SMB 客 户 程 序/ 服 务 器 程 序 的 软 件 包, 其 功 能 是 实 现Windows 和Linux 互 相 共 享 对 方 的 磁 盘 空 间 和 打 印 机。通用网络文件系统简称CIFS,它事实上是windows平台文件共享的标准协议,它是windows explorer,网络邻居和映射网络驱动器的底层实现协议。JAVA具有天然的平台无关性,使用JAVA可以访问任何类型的服务器或客户机上的共享文件系统,并且编写的软件产品可以运行于任何平台,因此用JAVA访问共享文件系统在企业应用中具有得天独厚的优势。
JAVA中的CIFS实现
Jcifs是CIFS在JAVA中的一个实现,是samba组织本着linux的精神,负责维护开发的一个开源项目。这个项目专注于使用java语言对cifs协议的设计和实现。他们将jcifs设计成为一个完整的,丰富的,具有可扩展能力且线程安全的客户端库。这一库可以应用于各种java虚拟机访问遵循CIFS/SMB网络传输协议的网络资源。类似于java.io.File的接口形式,在多线程的工作方式下被证明是有效而容易使用的。目前jcifs的最新版本是jcifs-0.8.0b,你可以在本文最后列出的参考资料中获得下载这一类库的网址,这一版本还支持分布式的文件系统,本文尚不涉及这一内容。
JAVA/CIFS程序设计
如果你曾经使用过java的文件操作功能,那么你将很容易掌握jcifs的开发方法。Jcifs通过类似如下的资源url定位一个资源:
smb://guest:1234@192.168.3.56/share/a.txt
这个url的开始部分smb:// 说明了这是一个smb类型的url;接下来的guest和1234分别是访问共享资源的用户名称和密码;@后面是要访问的资源的主机名或IP地址。最后是资源的共享文件夹名称和共享资源名。
在JAVA程序中,使用如下方式获得一个远程共享文件的句柄:
SmbFile file = new SmbFile("smb://guest:1234@192.168.3.56/share/a.txt");
这里的句柄不仅限于远程的共享文件,还可能是共享文件夹。isFile()方法和isDirectory()用来判断这个句柄对应的资源的真实属性。如果是共享文件夹,通过调用它的list()方法将获得其中资源的列表。List方法支持过滤器机制,有两种过滤器可供使用,一种是SmbFileFilter,另一种是SmbFilenameFilter,这两个在jcifs中作为接口出现,你可以根据自己的需要派生出个性化的过滤器,实现接口中的accept方法,以满足不同业务的需求。
SmbFileInputStream是smb文件的输入流,它的功能是以流的方式打开一个SmbFile:
SmbFileInputStream in = new SmbFileInputStream(file);
SmbFileInputStream提供read方法,你可以从这个流中读出远程文件全部的内容。
至此,你已经掌握了java访问smb文件系统的基本方法。
SmbFileOutputStream是smb文件的输入流,可以向远程文件系统通过smb写入数据,方法与上面类似,不再赘述。
本文后面附带的源代码是一个完整的例子,它完成功能很简单,就是将另一台电脑上指定共享文件夹下的某些文件拷贝到本机的指定目录下。通过这个例子,相信你很容易将它移植到你的开发产品中。
第一步,设置运行环境。将源代码解压缩,将lib目录下的名称为jcifs-0.8.0b.jar的文件加入到你的操作系统的classpath中,使示例程序运行时能够找到这个库。
第二步,在另一台计算机上建立名称为share的共享文件夹,用户名为guest,密码也为guest。假设这台计算机的ip地址是192.168.0.2。
第三步,在刚才建立的共享文件夹下放置两个文件,名称分别为hello.txt,bye.txt。文件的内容无所谓。
第三步,在本地计算机上的C盘跟目录下建立一个名称为tmp的空目录,置此目录可写。
第四步,编译运行Sample1.java,并运行:
Java Sample1 192.168.3.52 guest guest /share/ c:/tmp/
检查c:\tmp文件夹,会发现hello.txt这个文件被复制到了本机,而bye.txt没有被复制,因为Sample1.java中使用了过滤器,仅允许名称为hello开头的文件被拷贝。
后记
对共享文件系统的访问是内部办公系统等涉及到文件迁移的软件产品开发过程中不可回避的课题,jCifs是一套针对这一课题完整而强大的解决方案,通过它你可以实现对任何共享文件系统的访问。