差異處
這裏顯示兩個版本的差異處。
java:jcifs [2015/09/13 23:08] 127.0.0.1 外部編輯 |
java:jcifs [2017/08/19 23:33] |
||
---|---|---|---|
行 1: | 行 1: | ||
- | {{tag>java}} | ||
- | ====== JCIFS ====== | ||
- | ===== Introduction ===== | ||
- | JCIFS是java-based存取網路芳鄰通訊協定的API。\\ | ||
- | \\ | ||
- | 之所以接觸這個API,是因為好奇Windows管理工具[[http://blog.xuite.net/jyoutw/xtech/24607577-PsTools+%E4%B9%8B+PsExec+%E7%9A%84%E7%94%A8%E6%B3%95|psexec]],能將Local程式放到Remote並執行的做法。後來看到類似工具[[http://www.poweradmin.com/paexec/|paexec]]程式碼,與經過自己的測試,發現原理是將程式複製到遠端的[[http://en.wikipedia.org/wiki/Administrative_share|管理共享資料夾]],再透過WMI呼叫外部程式。\\ | ||
- | \\ | ||
- | 接下來將說明我有使用的API。 | ||
- | ===== How to? ===== | ||
- | 首先至[[http://jcifs.samba.org/src/|link]]下載library。接下來就是寫寫寫。 | ||
- | ==== Create File ==== | ||
- | 大部分的操作都可以透過SmbFile類別完成。而與遠端的機器認證,是透過[[http://www.rfjh.ntpc.edu.tw/web/html/teacher/html/ntlm.htm|NTLM通訊協定]]。 | ||
- | <code java> | ||
- | private static NtlmPasswordAuthentication createAuth(String aUser, String aPasswd){ | ||
- | StringBuffer sb = new StringBuffer(aUser); | ||
- | sb.append(':').append(aPasswd); | ||
- | return new NtlmPasswordAuthentication(sb.toString()); | ||
- | } | ||
- | |||
- | public static SmbFile createSmbFile(String aUser, String aPasswd, String aTarget) throws IOException { | ||
- | NtlmPasswordAuthentication auth = createAuth(aUser, aPasswd); | ||
- | return new SmbFile(aTarget, auth); | ||
- | } | ||
- | </code> | ||
- | 如果有網域,可以使用 | ||
- | <code java> | ||
- | new NtlmPasswordAuthentication(domain, user, passwd); | ||
- | </code> | ||
- | 在建立完SmbFile物件後,剩下其實就和操作一般檔案無異。 | ||
- | <code java> | ||
- | public static void createFile(String aUser, String aPasswd, String aTarget, String aContent) throws IOException { | ||
- | SmbFile sFile = createSmbFile(aUser, aPasswd, aTarget); | ||
- | SmbFileOutputStream sfos = null; | ||
- | try { | ||
- | sfos = new SmbFileOutputStream(sFile); | ||
- | sfos.write(aContent.getBytes()); | ||
- | } finally { | ||
- | close(sfos); | ||
- | } | ||
- | } | ||
- | </code> | ||
- | 最後是關閉串流的處理。 | ||
- | <code java> | ||
- | private static void close(Closeable aCloseable){ | ||
- | if( aCloseable == null ) | ||
- | return; | ||
- | |||
- | try { | ||
- | aCloseable.close(); | ||
- | } catch (IOException e) { | ||
- | // log exception | ||
- | } | ||
- | } | ||
- | </code> | ||
- | ==== Delete File ==== | ||
- | 刪除檔案: | ||
- | <code java> | ||
- | public static void deleteFile(String aUser, String aPasswd, String aTarget) throws IOException { | ||
- | SmbFile sFile = createSmbFile(aUser, aPasswd, aTarget); | ||
- | sFile.delete(); | ||
- | } | ||
- | </code> | ||
- | ==== Exist ==== | ||
- | 確認檔案是否存在: | ||
- | <code java> | ||
- | public static boolean exists(String aUser, String aPasswd, String aTarget) throws IOException { | ||
- | SmbFile sFile = createSmbFile(aUser, aPasswd, aTarget); | ||
- | return sFile.exists(); | ||
- | } | ||
- | </code> | ||
- | ==== Copy File ==== | ||
- | 複製本地檔案到遠端: | ||
- | <code java> | ||
- | public static void copyFileTo(String aUser, String aPasswd, String aSource, String aTarget) throws IOException { | ||
- | SmbFile sFile = createSmbFile(aUser, aPasswd, aTarget); | ||
- | SmbFileOutputStream sfos = null; | ||
- | FileInputStream fis = null; | ||
- | try { | ||
- | sfos = new SmbFileOutputStream(sFile); | ||
- | fis = new FileInputStream(new File(aSource)); | ||
- | byte[] buf = new byte[1024]; | ||
- | int len; | ||
- | while(( len = fis.read(buf) )> 0 ){ | ||
- | sfos.write(buf, 0, len); | ||
- | } | ||
- | } finally { | ||
- | close(sfos); | ||
- | close(fis); | ||
- | } | ||
- | } | ||
- | </code> | ||
- | 複製遠端檔案到本地: | ||
- | <code java> | ||
- | public static void copyFileFrom(String aUser, String aPasswd, String aSource, String aTarget) throws IOException { | ||
- | SmbFile sFile = createSmbFile(aUser, aPasswd, aSource); | ||
- | SmbFileInputStream sfis = null; | ||
- | FileOutputStream fos = null; | ||
- | try { | ||
- | sfis = new SmbFileInputStream(sFile); | ||
- | fos = new FileOutputStream(new File(aTarget)); | ||
- | |||
- | byte[] buf = new byte[1024]; | ||
- | int len; | ||
- | while(( len = sfis.read(buf) )> 0 ){ | ||
- | fos.write(buf, 0, len); | ||
- | } | ||
- | } finally { | ||
- | close(sfis); | ||
- | close(fos); | ||
- | } | ||
- | } | ||
- | </code> | ||
- | ===== Test ===== | ||
- | 簡單的寫了對檔案建立與複製的單元測試,這是對某台Win7機器的管理共享做存取。 | ||
- | <code java> | ||
- | public class SmbFileUtilTest { | ||
- | |||
- | private String targetFolder = "smb://192.168.1.25/admin$/"; | ||
- | private String user = "administrator"; | ||
- | private String passwd = "123456"; | ||
- | |||
- | private String remoteTmpFile = null; | ||
- | private String localTmpFile = null; | ||
- | |||
- | @After | ||
- | public void tearDown() throws IOException{ | ||
- | if( remoteTmpFile != null ){ | ||
- | SmbFileUtil.deleteFile(user, passwd, remoteTmpFile); | ||
- | assertFalse(SmbFileUtil.exists(user, passwd, remoteTmpFile)); | ||
- | } | ||
- | if( localTmpFile != null ){ | ||
- | new File(localTmpFile).delete(); | ||
- | } | ||
- | } | ||
- | |||
- | @Test | ||
- | public void copyFile() throws IOException{ | ||
- | remoteTmpFile = targetFolder+"temp.txt"; | ||
- | localTmpFile = "temp.tmp"; | ||
- | SmbFileUtil.copyFileTo(user, passwd, "libs/jcifs-1.3.18.jar", remoteTmpFile); | ||
- | assertTrue(SmbFileUtil.exists(user, passwd, remoteTmpFile)); | ||
- | |||
- | SmbFileUtil.copyFileFrom(user, passwd, remoteTmpFile, localTmpFile); | ||
- | File localFile = new File(localTmpFile); | ||
- | assertTrue(localFile.exists()); | ||
- | |||
- | assertEquals(new File("libs/jcifs-1.3.18.jar").length(), localFile.length()); | ||
- | } | ||
- | |||
- | @Test | ||
- | public void createFile() throws IOException{ | ||
- | remoteTmpFile = targetFolder+"temp.txt"; | ||
- | SmbFileUtil.createFile(user, passwd , remoteTmpFile, "test"); | ||
- | assertTrue(SmbFileUtil.exists(user, passwd, remoteTmpFile)); | ||
- | } | ||
- | } | ||
- | </code> | ||
- | ===== Summary ===== | ||
- | 要將檔案複製到遠端,也可以透過 | ||
- | - 在本地建立網芳或Samba Server,讓遠端由本地複製檔案。 | ||
- | - 使用echo在遠端建立wget的VB Script,從本地的http server去wget檔案。 | ||
- | 不管是以上兩種方法,或是透過管理共享,都是有可能因為使用者權限與安全性設定而失敗。只能見招拆招了。 | ||
- | ===== Reference ===== | ||
- | * [[http://jcifs.samba.org/|JCIFS official site]] | ||
- | * [[http://sanjaal.com/java/875/java-utilities/java-tutorial-using-jcifs-to-copy-files-to-shared-network-drive-using-username-and-password/|Copy File]] | ||
- | * [[http://stackoverflow.com/questions/14749434/how-to-copy-file-from-smb-share-to-local-drive-not-in-domain-with-jcifs|JCIFS with domain]] |