通過jcifs實現java訪問網絡共享文件
問題:
1,windows本地服務localsystem帳戶默認對本地操作系統具有最高操作權限,但是卻不能對網絡資源訪問。
2,經過測試發現用windows服務不能訪問網絡共享文件夾,同樣的程序在windows應用程序及控制臺程序中運行卻可以。
注:通過共享文件夾 能夠訪問
考慮方法:
方法一:一般service服務默認的啟動身份是local SYSTEM,把自定義服務的屬性修改一下,把log on改成用管理員帳戶登入(在windows服務列表中點該服務的屬性)
試過還是不行.
方法二:現在是通過windows的網絡映射驅動器,把該共享文件映射到本地為“I盤“,java代碼如下:
File file = new File("I:/Share");
file.exists();
無法訪問,報文件不存在。
方法三:就是下面要講述的基于SMB協議,現在又叫CIFS協議的Java開源項目JCIFS。
SMB(Server Message Block):通信協議是微軟(Microsoft)和英特爾(Intel)在1987年制定的協議,主要是作為Microsoft網絡的通訊協議。SMB 是在會話層(session layer)和表示層(presentation layer)以及小部分應用層(application layer)的協議。SMB使用了NetBIOS的應用程序接口 (Application Program Interface,簡稱API)。另外,它是一個開放性的協議,允許了協議擴展——使得它變得更大而且復雜;大約有65個最上層的作業,而每個作業都超過120個函數,甚至Windows NT也沒有全部支持到,最近微軟又把 SMB 改名為 CIFS(Common Internet ile System),并且加入了許多新的特色。
SMB協議是基于TCP-NETBIOS下的,一般端口使用為139,445
CIFS(Common Internet File System):通用Internet文件系統
在windows主機之間進行網絡文件共享是通過使用微軟公司自己的CIFS服務實現的。
CIFS 是一個新提出的協議,它使程序可以訪問遠程Internet計算機上的文件并要求此計算機的服務。CIFS 使用客戶/服務器模式。客戶程序請求遠在服務器上的服務器程序為它提供服務。服務器獲得請求并返回響應。CIFS是公共的或開放的SMB協議版本,并由Microsoft使用。SMB協議現在是局域網上用于服務器文件訪問和打印的協議。象SMB協議一樣,CIFS在高層運行,而不象TCP/IP協議那樣運行在底層。CIFS可以看做是應用程序協議如文件傳輸協議和超文本傳輸協議的一個實現。
CIFS 可以使您達到以下功能:
1.訪問服務器本地文件并讀寫這些文件
2.與其它用戶一起共享一些文件塊
3.在斷線時自動恢復與網絡的連接
4.使用西歐字符文件名
一般來說,CIFS使用戶得到比FTP更好的對文件的控制。它提供潛在的更直接地服務器程序接口,這比使用HTTP協議的瀏覽器更好。CIFS最典型的應用是windows用戶能夠從“網上鄰居”中找到網絡中的其他主機并訪問其中的共享文件夾.
CIFS 是開放的標準而且已經被作為Internet應用程序標準被提交到IETF。
開源項目—JCIFS
JCIFS是CIFS 在JAVA中的一個實現,是samba組織負責維護開發的一個開源項目,專注于使用java語言對cifs協議的設計和實現。他們將jcifs設計成為一個完整的,豐富的,具有可擴展能力且線程安全的客戶端庫。這一庫可以應用于各種java虛擬機訪問遵循CIFS/SMB網絡傳輸協議的網絡資源。類似于java.io.File的接口形式,在多線程的工作方式下被證明是有效而容易使用的。
JCIFS的開發方法類似java的文件操作功能,它的資源url定位:smb://{user}:{password}@{host}/{path},smb為協議名,user和password分別為共享文件機子的登陸名和密碼,@后面是要訪問的資源的主機名或IP地址。最后是資源的共享文件夾名稱和共享資源名。例如 smb://administrator:122122@192.168.0.22/test/response.txt。
在JAVA程序中,使用如下方式獲得一個遠程共享文件的句柄:SmbFile file = new SmbFile("smb://guest:1234@192.168.3.56/share/a.txt");這里的句柄不僅限于遠程的共享文件,還可能是共享文件夾。isFile()方法和isDirectory()用來判斷這個句柄對應的資源的真實屬性。如果是共享文件夾,通過調用它的list()方法將獲得其中資源的列表。List方法支持過濾器機制,有兩種過濾器可供使用,一種是SmbFileFilter,另一種是SmbFilenameFilter,這兩個在jcifs中作為接口出現,你可以根據自己的需要派生出個性化的過濾器,實現接口中的accept方法,以滿足不同業務的需求。
參考網站:http://jcifs.samba.org/
JAVA中的CIFS實現
Jcifs是CIFS在JAVA中的一個實現,是samba組織本著linux的精神,負責維護開發的一個開源項目。這個項目專注于使用java語言對cifs協議的設計和實現。他們將jcifs設計成為一個完整的,豐富的,具有可擴展能力且線程安全的客戶端庫。這一庫可以應用于各種java虛擬機訪問遵循CIFS/SMB網絡傳輸協議的網絡資源。類似于java.io.File的接口形式,在多線程的工作方式下被證實是有效而輕易使用的。
簡單示例:
import jcifs.smb.SmbFile; import jcifs.smb.SmbFileInputStream; public class RemoteAccessData { public static void main(String[] args) { try { SmbFile smbFile = new SmbFile("smb://guest:1234@192.168.3.56/share/a.txt"); int length = smbFile.getContentLength();//得到文件的大小 byte buffer[] = new byte[length]; SmbFileInputStream in = new SmbFileInputStream(smbFile); //建立smb文件輸入流 while ((in.read(buffer)) != -1) { System.out.write(buffer); System.out.println(buffer.length); } in.close(); } catch (Exception e) { e.printStackTrace(); } } }
remoteUrl說明:
如果是無需密碼的共享,則類似如下格式:
smb://ip/sharefolder(例如:smb://192.168.0.77/test)
如果需要用戶名、密碼,則類似如下格式:
Smb://username:password@ip/sharefolder(例如:smb://chb:123456@192.168.0.1/test)
注:jcifs.smb包下的很多方法,如SmbFile,SmbFileInputStream,SmbRandomAccessFile等等很多類,基本上和java.io包下的文件讀寫類
基本相同的,大體上在jdk的io類前面加上了它的標識“Smb”。