I'm trying to copy a file from my local machine to Shared folder in a windows server. This is the function which I used.
public static void copyFileUsingJcifs(final String domain, final String userName, final String password, final String sourcePath, final String destinationPath) throws IOException {
final NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(domain, userName, password);
final SmbFile sFile = new SmbFile(destinationPath, auth);
final SmbFileOutputStream smbFileOutputStream = new SmbFileOutputStream(sFile);
final FileInputStream fileInputStream = new FileInputStream(new File(
sourcePath));
final byte[] buf = new byte[16384];
int len;
while ((len = fileInputStream.read(buf)) > 0) {
smbFileOutputStream.write(buf, 0, len);
}
fileInputStream.close();
smbFileOutputStream.close();
}
I tried this answer, but didn't work for me. When I do normal copying(Copy and Paste) it only takes maximum of 8minutes for a 25MB file. But when I use my java program using this function its taking more than 20minutes. How can I make this copying faster?
Thanks in advance.
In case it helps others...I had a similar issue, but in the other direction (slow copying TO Windows using JCIFS). The issue was resolved by adding
-Djcifs.resolveOrder=DNS
to the property list. (The default inclusion of BCAST -- to send a NetBIOS name query broadcast to 255.255.255.255 -- is what was causing the enormous delay.)
I was having the same issue. Tried -Djcifs.resolveOrder=DNS with no luck. After reading a few comments with buffer size I decided to go to the extreme and really ramp it up. I know my transfer rate should be at least 50mb/s so I converted that to bytes and set it as my buffer and it worked as expected.
try this function its highly optimized if its still slow then increase buffer size in code . In my case it reduced time from 10 min to copy 48MB file to 1 min
public static boolean createCopyOnNetwork(String domain,String username,String password,String src, String dest) throws Exception
{
//FileInputStream in = null;
SmbFileOutputStream out = null;
BufferedInputStream inBuf = null;
try{
//jcifs.Config.setProperty("jcifs.smb.client.disablePlainTextPasswords","true");
NtlmPasswordAuthentication authentication = new NtlmPasswordAuthentication(domain,username,password); // replace with actual values
SmbFile file = new SmbFile(dest, authentication); // note the different format
//in = new FileInputStream(src);
inBuf = new BufferedInputStream(new FileInputStream(src));
out = (SmbFileOutputStream)file.getOutputStream();
byte[] buf = new byte[5242880];
int len;
while ((len = inBuf.read(buf)) > 0){
out.write(buf, 0, len);
}
}
catch(Exception ex)
{
throw ex;
}
finally{
try{
if(inBuf!=null)
inBuf.close();
if(out!=null)
out.close();
}
catch(Exception ex)
{}
}
System.out.print("\n File copied to destination");
return true;
}
What I noticed is that jCIFS does "something" (afair jcifs.smb.SmbTransport.checkStatus(..)) for every chunk it reads - i.e. for each chunk that is read into the buffer. That means increasing your buffer size might really speed things up, although the real problem still exists, but only occurs 1 or 2 times having a lower impact on the overall time..
It helps a lot to set "jcifs.util.loglevel=3" and have a look what's really wrong..
In my case I had to set "jcifs.smb.client.dfs.disabled=false" in the end, as "jcifs.resolveOrder=DNS" didn't help..
There are some new SMB java project that support SMB2 and above , I think you can give them a try.
- smbj - https://github.com/hierynomus/smbj - (Apache v2 license)
- jNQ - http://visualitynq.com/products/jnq-java-smb-client (commercial license)
Just note that SMB2 is better, faster and more secure than SMB1 (jCifs)