2012-11-13 1 views
6

Quelqu'un pourrait-il m'aider à copier le fichier du dossier partagé au disque local? Mon code est:Comment copier un fichier depuis un partage smb sur un disque local en utilisant jcifs en 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); 
     } 
} 

Le fichier de fichier n'est pas copié. J'ai reçu un message "Impossible de se connecter au serveur", mais le programme affiche dir.getDate() (et le nom du fichier et la longueur) du fichier source. Donc, je pense que le problème avec le dossier de destination (C:/SQLRESTORESTAGE /). Aussi, j'ai proviledges seulement pour lire le fichier source. Pourriez-vous m'aider à décrire le code ou à conseiller quelque chose? Je vous remercie.

Répondre

8

peut-être ajouter auth au deuxième fichier:

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

utilisant SmbFile dest = new SmbFile ("C:/SQLRESTORESTAGE",auth).canWrite savoir si vous disposez des droits d'écriture sur le répertoire parent

7

Après de nombreux essais et échecs la seule méthode qui a fonctionné pour moi fiable était d'aller à l'ancienne école et utiliser FileInputStream et FileOutputStream comme ça:

`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

Juste un petit mot, il est préférable de fermer vos flux dans un bloc finally. – PomCompot

+0

Pour ajouter au commentaire de @PomCompot, je suggère également d'utiliser Apache Commons IO et d'utiliser 'IOUtils.closeQuietly (Closeable c)' pour fermer vos flux dans le bloc 'finally'. Il ignore discrètement toutes les exceptions soulevées en appelant 'close()' sur le flux, alors soyez conscient de cette mise en garde, même si je n'ai pas encore trouvé personnellement qu'il y ait un problème. – Will

+0

Au-dessus du code est travaillé pour moi Merci. –

-2

vous devez utiliser le fichier: protocole

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

Je l'ai eu pour travailler. J'ai dû 'créer' le fichier de destination avant de faire la copie. essayez d'ajouter la ligne du milieu ci-dessous dans votre extrait de code original et voyez si cela fonctionne.

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

Je reçois "Échec d'ouverture de session: nom d'utilisateur inconnu ou mot de passe incorrect." exception si les informations d'identification sont correctes. Quelqu'un peut-il m'en parler? J'utilise le même code que ci-dessus – tejas

1

Ceci est à titre de clarification. "Échec d'ouverture de session: nom d'utilisateur inconnu ou mot de passe incorrect." peut montrer par exemple lorsque vous utilisez 1.3.18 mais pas dans 1.2.25. il est probablement parce que les différents paramètres de compatibilité:

  1. jcifs.smb.lmCompatibility = 0 ou 1: Envoyer LM et NTLM 2)
  2. jcifs.smb.lmCompatibility = 2: Envoyer NTLM dans les deux champs 3)
  3. jcifs.smb.lmCompatibility = 3, 4 ou 5: Envoyer juste LMv2

la première façon consiste à utiliser avant NtlmPasswordAuthentication

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

Il peut résoudre ce problème.

Questions connexes