7

Could anybody help me to copy file from shared folder to local drive? My code is:

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


public class smb {

      /**
      * @param args
      * @throws IOException
       */
      public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub


          String urlToBackUpFile = "smb://ip/backup$/test.txt"; 
          System.out.println("smb folder of source file" + urlToBackUpFile);
          NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(null, "login", "pass");


            SmbFile dir = new SmbFile(urlToBackUpFile, auth);
            System.out.println(dir.getDate());
            SmbFile dest = new SmbFile ("C:/SQLRESTORESTAGE/v2.bak");
            dir.copyTo(dest);
      }
}

File file is not copied. I received a message "Failed to connect to server", but the programm shows dir.getDate() (and file name, and lenght) of source file. So I think the problem with destination folder (C:/SQLRESTORESTAGE/). Also I have proviledges only for reading source file. Could you help me to cirrect the code or advise something? Thank you.

May12
  • 2,420
  • 12
  • 63
  • 99

5 Answers5

8

maybe adding auth to the second file:

SmbFile dest = new SmbFile ("C:/SQLRESTORESTAGE/v2.bak",**auth**);

using SmbFile dest = new SmbFile ("C:/SQLRESTORESTAGE",auth).canWrite you know if you have write permissions on the parent directory

nagualjj
  • 96
  • 1
8

After many trials and failures the only method that worked for me reliably was to go old school and use FileInputStream and FileOutputStream like so:

   `SmbFile[] files = getSMBListOfFiles(sb, logger, domain, userName, password, sourcePath, sourcePattern);

    if (files == null)
        return false;
    output(sb, logger, "      Source file count: " + files.length);
    String destFilename;
    FileOutputStream fileOutputStream;
    InputStream fileInputStream;
    byte[] buf;
    int len;
    for (SmbFile smbFile: files) {
        destFilename = destinationPath + smbFile.getName();
        output(sb, logger, "         copying " + smbFile.getName());
        try {
            fileOutputStream = new FileOutputStream(destFilename);
            fileInputStream = smbFile.getInputStream();
            buf = new byte[16 * 1024 * 1024];
            while ((len = fileInputStream.read(buf)) > 0) {
                fileOutputStream.write(buf, 0, len);
            }
            fileInputStream.close();
            fileOutputStream.close();
        } catch (SmbException e) {
            OutputHandler.output(sb, logger, "Exception during copyNetworkFilesToLocal stream to output, SMP issue: " + e.getMessage(), e);
            e.printStackTrace();
            return false;
        } catch (FileNotFoundException e) {
            OutputHandler.output(sb, logger, "Exception during copyNetworkFilesToLocal stream to output, file not found: " + e.getMessage(), e);
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            OutputHandler.output(sb, logger, "Exception during copyNetworkFilesToLocal stream to output, IO problem: " + e.getMessage(), e);
            e.printStackTrace();
            return false;
        }
    }`
  • 3
    Just a little note, it's better to close your streams in a finally block. – Doc Davluz Jan 30 '14 at 09:07
  • To add to @PomCompot 's comment, I would also suggest making use of Apache Commons IO and use `IOUtils.closeQuietly(Closeable c)` to close your streams in the `finally` block. It quietly ignores any exceptions raised by calling `close()` on the stream, so be aware of that caveat, though I have yet to find it personally to be an issue. – Will Nov 05 '15 at 17:09
3

I got it to work. I had to 'create' the destination file before doing the copy. try adding the middle line below into your original code-snippet and see if that works.

SmbFile dest = new SmbFile ("C:/SQLRESTORESTAGE/v2.bak");
dest.createNewFile();
dir.copyTo(dest);
GregM
  • 31
  • 1
  • 2
    I am getting "Logon failure: unknown user name or bad password." exception though the credentials are correct. Can anybody tell me about this? I am using the same code as above – tejas Feb 10 '15 at 06:53
2

This is for clarification. "Logon failure: unknown user name or bad password." can show for example when you use 1.3.18 but not in 1.2.25. it is probably because different compatibility settings:

  1. jcifs.smb.lmCompatibility = 0 or 1: Send LM and NTLM 2)
  2. jcifs.smb.lmCompatibility = 2: Send NTLM in both fields 3)
  3. jcifs.smb.lmCompatibility = 3, 4, or 5: Send just LMv2

First way is to use it before NtlmPasswordAuthentication

jcifs.Config.setProperty( "jcifs.smb.lmCompatibility", "3");

It can resolve this issue.

jareeq
  • 311
  • 2
  • 9
-2

you must use the file: protocol

SmbFile dest = new SmbFile ("file:" + "C:/SQLRESTORESTAGE/v2.bak");
JSK NS
  • 3,346
  • 2
  • 25
  • 42