Sunday, December 16, 2012

Copying the resources to and from windows network using Java



Using JCIFS - In this approach we use the implementation of CIFS (Common Internet File System) protocol, which is used for file sharing in windows.  File copy using this  approach is bit slower but suitable on the instances when the user running the program does not have direct access to the network folder and require to pass credentials to access. The sample code to copy file in network drive is as mentioned below - 

Required maven dependency -

<dependency>
 <groupId>org.samba.jcifs</groupId>
 <artifactId>jcifs</artifactId>
 <version>1.2.19</version>
</dependency> 

Sample code -

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileOutputStream;

public class CopyFileUsingJCIFS {

 public static void main(String[] args) throws IOException {
  final String userName = "UserName";
  final String password = "Password";
  final String sourcePath = "pom.xml";
  final String destinationPath = "smb://SALIL-HP/Temp/pom.xml";

  copyFileUsingJcifs(userName, password, sourcePath, destinationPath);

  System.out.println("The file has been copied using JCIFS");
 }
 
 public static void copyFileUsingJcifs(final String userName,
   final String password, final String sourcePath,
   final String destinationPath) throws IOException {

  final String user = userName + ":" + password;
  final NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(
    user);
  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[16 * 1024 * 1024];
  int len;
  while ((len = fileInputStream.read(buf)) > 0) {
   smbFileOutputStream.write(buf, 0, len);
  }
  fileInputStream.close();
  smbFileOutputStream.close();
 }
}

 

Using  pure Java IO - This hand coded approach provides better performance than JCIFS but require the user running the java program to have direct access to the network resource. In this case we do not need to import any additional library. The sample code is as mentioned below -

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyingFile {

 public static void main(String[] args) throws IOException {
  final String sourcePath = "pom.xml";
  final String destinationPath = "//SALIL-HP/Temp/pom.xml";

  copyFile(sourcePath, destinationPath);

  System.out.println("The file has been copied using java");
 }

 public static void copyFile(final String sourcePath,
   final String destinationPath) throws IOException {

  final FileOutputStream fileOutputStream = new FileOutputStream(
    destinationPath);
  final FileInputStream fileInputStream = new FileInputStream(new File(
    sourcePath));

  final byte[] buf = new byte[16 * 1024 * 1024];
  int len;
  while ((len = fileInputStream.read(buf)) > 0) {
   fileOutputStream.write(buf, 0, len);
  }
  fileInputStream.close();
  fileOutputStream.close();
 }
}
 



Using commons-io  -  Apache provides FileUtils api, which contains multiple utility functions along with multiple utility methods of copying resources from one folder to network location. In this case code to write will be very small but we will need to include commons-io jar file in the project and user running the program would need to have direct access to the network resources.
The sample code is as mentioned below -

Required maven dependency - 


<dependency>
 <groupId>org.apache.commons</groupId>
 <artifactId>commons-io</artifactId>
 <version>1.3.2</version>
</dependency>

Sample Code
import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FileUtils;

public class CopyFileUsingCommonIO {

 public static void main(String[] args) throws IOException {
  FileUtils.copyFileToDirectory(new File("pom.xml"), new File("//SALIL-HP/Temp"));
 }
}
 



6 comments:

  1. Thank you .. Thank you ... Thank you.. Great Post

    ReplyDelete
  2. Good job thank's so much , love't

    ReplyDelete
  3. You are welcome. It's good to know that my post could be of some use for you.

    ReplyDelete


  4. import jcifs.smb.*;
    public class Smb {

    //@SuppressWarnings("unused")
    public static void main(String[] args) throws Exception {
    try {
    SmbFile f = null;
    String serverAddress = "linuxserver.com";
    String sharename = "tempfolder";
    String USER_NAME = "srctest";
    String PASSWORD = "*********";


    jcifs.Config.setProperty( "jcfis.resolveOrder","DNS");
    jcifs.Config.setProperty( "jcifs.util.loglevel","10");
    jcifs.Config.setProperty( "jcifs.netbios.retryTimeout", "150000");
    jcifs.Config.setProperty("jcifs.smb.client.responseTimeout", "150000");
    jcifs.Config.setProperty("jcifs.smb.client.soTimeout","150000");
    jcifs.Config.setProperty("jcifs.smb.client.dfs.disabled","true");
    jcifs.Config.setProperty("jcifs.smb.client.signingPreferred", "true");
    jcifs.Config.setProperty("jcifs.smb.client.attrExpirationPeriod", "0");
    jcifs.Config.setProperty("jcifs.netbios.cachePolicy","0");
    jcifs.Config.setProperty("jcifs.smb.client.dfs.strictView", "true");
    jcifs.Config.setProperty("jcifs.netbios.wins", "linuxserver.com" );
    // I tried with IP Address as well



    NtlmPasswordAuthentication ntlmPasswordAuthentication = new NtlmPasswordAuthentication(null, USER_NAME,PASSWORD);

    f = new SmbFile("smb://"+serverAddress+"/"+sharename+"/" ,ntlmPasswordAuthentication);

    System.out.println(f);

    System.out.println(f.getPermission());

    for (SmbFile fs : f.listFiles()) {
    System.out.println(fs.getName());
    }


    } catch (Exception e) {
    System.out.println(e);
    }
    }
    }


    I'm running the above code from my local desktop to connect to Linux server using JCIFS. Getting teh below error:

    ("java.security.AllPermission" "" "")
    jcifs.smb.SmbException: Failed to connect:
    jcifs.util.transport.TransportException
    java.net.ConnectException: Connection timed out: connect linuxserver.com
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at jcifs.smb.SmbTransport.ssn139(SmbTransport.java:196)
    at jcifs.smb.SmbTransport.negotiate(SmbTransport.java:249)
    at jcifs.smb.SmbTransport.doConnect(SmbTransport.java:322)
    at jcifs.util.transport.Transport.run(Transport.java:241)
    at java.lang.Thread.run(Thread.java:745)

    at jcifs.util.transport.Transport.run(Transport.java:258)
    at java.lang.Thread.run(Thread.java:745)

    Could you help me where I'm getting this thing wrong?

    ReplyDelete