Как скопировать файл из 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. вероятно, это связано с различными настройками совместимости:
- jcifs.МСБ.lmCompatibility = 0 или 1: отправить LM и NTLM 2)
- jcifs.МСБ.lmCompatibility = 2: отправить NTLM в обоих полях 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");