如何使用JCIFS将文件从SMB共享复制到不在域中的本地驱动器

时间:2013-02-07 10:57:03

标签: smb jcifs

我正在尝试使用JCIFS将一些远程文件复制到Java中的本地驱动器。 远程计算机位于域内。域中的本地计算机

以下代码有效,但它真的慢(700Kb为2分钟......我有很多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?

有关

3 个答案:

答案 0 :(得分: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秒

bufferSize = 50240经过时间:3.8876541543秒

bufferSize = 100240经过时间:3.742167582秒

答案 1 :(得分:4)

除了以及有效的 smb 网址外,无法构建SmbFile对象。请参阅http://jcifs.samba.org/src/docs/api/处的构造函数摘要,以及有关顶部SmbFile URL的讨论。

  

SmbFile URL具有以下语法:   SMB:// [[[域]用户名[:密码] @]服务器[:端口] / [[份额/ [DIR /]文件]]]?[[PARAM =值[参数2 = 2 [...] ]

因此,如果您真的想避免使用输入流并使用copyTo(),那么您必须在本地计算机上拥有一个可以指向jCIFS的SMB共享。

如果您的本地计算机是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,则必须再次使用。

答案 2 :(得分:4)

作为@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使用的默认值相对较好。