2013-02-07 40 views
3

我試圖使用JCIFS將一些遠程文件複製到Java本地驅動器。 遠程機器在域內。本地機器在域中是而不是如何將文件從SMB共享複製到本地驅動器不在與JCIFS的域中

下面的代碼工作,但它是真的(2分鐘,700KB ...我有許多MB ...):

SmbFile remoteFile = new SmbFile("smb://...") 
OutputStream os = new FileOutputStream("/path/to/local/file"); 
InputStream is = remoteFile.getInputStream(); 
int ch; 
while ((ch = is.read()) != -1) { 
    os.write(ch); 
} 
os.close(); 
is.close(); 

我想我可以使用SmbFile.copyTo() ,但我不知道如何訪問本地文件。如果我寫了下面,我得到一個連接錯誤:

localfile = new SmbFile("file:///path/to/localfile") 

這個問題是關係到How to copy file from smb share to local drive using jcifs in Java?

回答

4

的SmbFile對象不能構建除了有一個有效的SMB URL。請參閱構造函數摘要http://jcifs.samba.org/src/docs/api/以及關於頂部的SmbFile URL的討論。

SmbFile URLs have the following syntax: smb://[[[domain;]username[:password]@]server[:port]/[[share/[dir/]file]]][?[param=value[param2=value2[...]]]

所以,如果你真的想避免使用輸入流,並使用CopyTo從(),你必須有你的本地計算機上的SMB共享,​​你可以點到JCIFS。

如果您的本地計算機是Windows計算機,則可能會有一些默認共享,例如C $。

所以,你可以這樣做:

NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("domain", "username", "password") //or whatever authentication works on your local machine. 
SmbFile myFile = new SmbFile("smb://localhost/C\$/path/to/localfile", auth) 

那麼你可以使用remoteFile.copyTo(myFile)

如果您不在Windows主機上,您將不得不安裝Samba並設置Samba共享以連接到本地計算機......如果您絕對傾向於避免使用inputStream,則必須再次進行連接。

+0

值得注意的是,nagualjj表示你也可以使用格式「C:/ path/to/file」,但是我沒有成功這樣做。 http://stackoverflow.com/questions/13359164/ – jonnybot

+0

什麼是'remoteFile'? – Jaikrat

+0

從最初的問題來看,'remoteFile'是OP要複製到另一個位置(在本例中爲'myFile')的SmbFile。 – jonnybot

5

你只需要做出更大的緩衝:

SmbFile remoteFile = new SmbFile("smb://...") 
    OutputStream os = new FileOutputStream("/path/to/local/file"); 
    InputStream is = remoteFile.getInputStream(); 

        int bufferSize = 5096; 

        byte[] b = new byte[bufferSize]; 
        int noOfBytes = 0; 
         while((noOfBytes = is.read(b)) != -1) 
        { 
         os.write(b, 0, noOfBytes); 
        } 
        os.close(); 
        is.close(); 

這裏的一些測試,我用文件23 MB完成後,使用所提到的代碼。

BUFFERSIZE = 1024]經過時間:10.9587606066秒

BUFFERSIZE = 4096]經過時間:5.6239662951秒

BUFFERSIZE = 5096]經過時間:5.0798761245秒

BUFFERSIZE = 5096]經過時間:4.879439883秒

bufferSize = 10240運行時間:4.0192989201 sec

bufferSize = 5024 0已用時間:3.8876541543 sec

bufferSize = 100240已用時間:3。742167582秒

+0

需要太多時間才能製作InputStream並將其複製到目標文件中。我有1KB文件,完成該活動需要1分多鐘。有什麼辦法可以讓它快速嗎? – Jaikrat

3

作爲替代@maxmimko的答案,你也可以讓使用Apache Commons IO庫,並使用IOUtils來爲您處理複印:

NtlmPasswordAuthentication creds = new NtlmPasswordAuthentication("domain", "user", "password"); 
SmbFile remoteFile = new SmbFile("smb://REMOTEHOST/SHARE/path/to/file", creds); 
try (
    InputStream is = remoteFile.getInputStream(); 
    OutputStream os = new FileOutputStream("/path/to/local/file"); 
) { 
    long bytesCopied = IOUtils.copyLarge(is, os); 
} catch (IOException e) { 
    // handle exception here; log it? 
} 
// streams are automatically closed by try-with-resources block 

還有IOUtils.copyLarge(InputStream is, OutputStream os, byte[] buffer),如果你想控制緩衝區大小,但我發現IOUtils使用的默認值在整個板子上都比較好。

相關問題