2012-11-13 14 views
6

Có ai có thể giúp tôi sao chép tệp từ thư mục được chia sẻ sang ổ đĩa cục bộ không? Mã của tôi là:Làm thế nào để sao chép tệp từ chia sẻ smb sang ổ đĩa cục bộ bằng cách sử dụng jcif trong 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); 
     } 
} 

Tệp tệp không được sao chép. Tôi đã nhận được thông báo "Không thể kết nối với máy chủ", nhưng chương trình hiển thị dir.getDate() (và tên tệp và chiều dài) của tệp nguồn. Vì vậy, tôi nghĩ rằng vấn đề với thư mục đích (C:/SQLRESTORESTAGE /). Ngoài ra tôi có những lời khiêu khích chỉ để đọc tệp nguồn. Bạn có thể giúp tôi cirrect mã hoặc tư vấn cho một cái gì đó? Cảm ơn bạn.

Trả lời

8

có thể thêm auth đến tập tin thứ hai:

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

sử dụng SmbFile dest = new SmbFile ("C:/SQLRESTORESTAGE",auth).canWrite bạn biết nếu bạn có quyền ghi vào thư mục cha

7

Sau nhiều thử nghiệm và thất bại phương pháp duy nhất mà làm việc cho tôi cách đáng tin cậy đã cắp sách đến trường cũ và sử dụng FileInputStream và FileOutputStream như vậy:

`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

Chỉ cần một lưu ý nhỏ, tốt hơn là đóng các luồng của bạn trong một khối cuối cùng. – PomCompot

+0

Để thêm vào nhận xét của @PomCompot, tôi cũng khuyên bạn nên sử dụng Apache Commons IO và sử dụng 'IOUtils.closeQuietly (Closeable c)' để đóng các luồng của bạn trong khối 'finally'. Nó lặng lẽ bỏ qua bất kỳ trường hợp ngoại lệ nào được nêu ra bằng cách gọi 'close()' trên luồng, vì vậy hãy chú ý đến cảnh báo đó, mặc dù tôi vẫn chưa thấy nó là một vấn đề. – Will

+0

Mã trên được làm việc cho tôi Cảm ơn. –

-2

bạn phải sử dụng file: giao thức

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

Tôi đã làm việc đó. Tôi phải 'tạo' tệp đích trước khi thực hiện sao chép. hãy thử thêm dòng giữa bên dưới vào đoạn mã gốc của bạn và xem nó có hoạt động hay không.

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

Tôi nhận được "Đăng nhập thất bại: tên người dùng không rõ hoặc mật khẩu sai." ngoại lệ mặc dù thông tin đăng nhập là chính xác. Ai có thể cho tôi biết về điều này? Tôi đang sử dụng cùng một mã như trên – tejas

1

Đây là cách để làm rõ. "Lỗi đăng nhập: tên người dùng không xác định hoặc mật khẩu không hợp lệ". có thể hiển thị ví dụ khi bạn sử dụng 1.3.18 nhưng không hiển thị trong 1.2.25. nó có lẽ là bởi vì các thiết lập tương thích khác nhau:

  1. jcifs.smb.lmCompatibility = 0 hoặc 1: Gửi LM và NTLM 2)
  2. jcifs.smb.lmCompatibility = 2: Gửi NTLM trong cả hai lĩnh vực 3)
  3. jcifs.smb.lmCompatibility = 3, 4, hoặc 5: chỉ cần gửi LMv2

cách đầu tiên là sử dụng nó trước khi NtlmPasswordAuthentication

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

Nó có thể giải quyết vấn đề này.

Các vấn đề liên quan