Как скопировать файл из SMB share на локальный диск с помощью jcifs в Java?

может ли кто-нибудь помочь мне скопировать файл из общей папки на локальный диск? Мой код:

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);
      }
}

файл файл не копируется. Я получил сообщение "не удалось подключиться к серверу", но программа показывает, реж.getDate() (и имя файла, и длина) исходного файла. Поэтому я думаю, что проблема с папкой назначения (C:/SQLRESTORESTAGE/). Также у меня есть proviledges только для чтения исходного файла. Могли бы вы помочь мне cirrect код или что-то посоветовать? Спасибо.

5 ответов


возможно, добавление auth во второй файл:

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

используя SmbFile dest = new SmbFile ("C:/SQLRESTORESTAGE",auth).canWrite вы знаете, есть ли у вас разрешения на запись в Родительском каталоге


после многих испытаний и неудач единственным методом, который работал для меня надежно, было пойти в старую школу и использовать FileInputStream и FileOutputStream следующим образом:

   `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;
        }
    }`

Это для разъяснения. "Ошибка входа: неизвестное имя пользователя или неверный пароль."можно показать, например, когда вы используете 1.3.18 но не в 1.2.25. вероятно, это связано с различными настройками совместимости:

  1. jcifs.МСБ.lmCompatibility = 0 или 1: отправить LM и NTLM 2)
  2. jcifs.МСБ.lmCompatibility = 2: отправить NTLM в обоих полях 3)
  3. jcifs.МСБ.lmCompatibility = 3, 4 или 5: отправить только LMv2

Первый способ-использовать его раньше NtlmPasswordAuthentication

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

Это может решить эту проблему.


Я заставил его работать. Перед копированием мне пришлось "создать" файл назначения. попробуйте добавить среднюю строку ниже в исходный фрагмент кода и посмотреть, работает ли это.

SmbFile dest = new SmbFile ("C:/SQLRESTORESTAGE/v2.bak");
dest.createNewFile();
dir.copyTo(dest);

вы должны использовать файл: протокол

SmbFile dest = new SmbFile ("file:" + "C:/SQLRESTORESTAGE/v2.bak");