1. 程式人生 > >Java使用SMBJ包從僅支援SMB2/SMB3協議的共享資料夾下載檔案

Java使用SMBJ包從僅支援SMB2/SMB3協議的共享資料夾下載檔案

說明

之前整理了一篇jcifs不能用於SMB2/SMB3機器的解決方式,其中提到了將jcifs包替換為smbj的方式解決,給出的下載的demo中雖然可以正常列出共享資料夾中的檔案,但是具體怎樣將共享資料夾中的檔案下載到本地並沒有詳細說明,現在將下載程式碼貼出,因為github上的jar包沒有給出API文件,現在的程式碼只是看原始檔找到的一種可行的下載方式,其中的部分引數等有時間再一併進行整理,如果有更好的下載方式歡迎留言

程式碼

package com.smb1.utils;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.EnumSet;
import java.util.concurrent.TimeUnit;

import com.hierynomus.msdtyp.AccessMask;
import com.hierynomus.msfscc.fileinformation.FileIdBothDirectoryInformation;
import com.hierynomus.mssmb2.SMB2CreateDisposition;
import com.hierynomus.mssmb2.SMB2ShareAccess;
import com.hierynomus.smbj.SMBClient;
import com.hierynomus.smbj.SmbConfig;
import com.hierynomus.smbj.auth.AuthenticationContext;
import com.hierynomus.smbj.connection.Connection;
import com.hierynomus.smbj.session.Session;
import com.hierynomus.smbj.share.DiskShare;
import com.hierynomus.smbj.share.File;

/**
 * SMB2連線示例
 * 例: 我們當前要連線 IP為:123.123.123.123 目錄為: SRC/SMB2/ 下的檔案 
 * @author liuyb
 *
 */
public class SMB2Connect {
	private static final String SHARE_DOMAIN = "計算機域名";
	private static final String SHARE_USER = "共享檔案設定的賬戶";
	private static final String SHARE_PASSWORD = "共享檔案設定的密碼";
	private static final String SHARE_SRC_DIR = "SRC/";
	private static final String SHARE_DST_DIR = "SMB2/";

	public static void main(String[] args) {
		// 設定超時時間(可選)
		SmbConfig config = SmbConfig.builder().withTimeout(120, TimeUnit.SECONDS)
				.withTimeout(120, TimeUnit.SECONDS) // 超時設定讀,寫和Transact超時(預設為60秒)
	            .withSoTimeout(180, TimeUnit.SECONDS) // Socket超時(預設為0秒)
	            .build();
		
		// 如果不設定超時時間	SMBClient client = new SMBClient();
		SMBClient client = new SMBClient(config);

		try {
			Connection connection = client.connect("IP或域名");	// 如:123.123.123.123
			AuthenticationContext ac = new AuthenticationContext(SHARE_USER, SHARE_PASSWORD.toCharArray(), SHARE_DOMAIN);
			Session session = connection.authenticate(ac);

			// 連線共享資料夾
			DiskShare share = (DiskShare) session.connectShare(SHARE_SRC_DIR);
			
			String folder = SHARE_SRC_DIR + SHARE_DST_DIR;
			String dstRoot = "要儲存的本地資料夾路徑";	// 如: D:/smd2/
			
			for (FileIdBothDirectoryInformation f : share.list(SHARE_DST_DIR, "*.mp4")) {
				String filePath = folder + f.getFileName();
				String dstPath = dstRoot + f.getFileName();
				
				FileOutputStream fos = new FileOutputStream(dstPath);
				BufferedOutputStream bos = new BufferedOutputStream(fos);
				
				if (share.fileExists(filePath)) {
					System.out.println("正在下載檔案:" + f.getFileName());
					
					File smbFileRead = share.openFile(filePath, EnumSet.of(AccessMask.GENERIC_READ), null, SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_OPEN, null);
					InputStream in = smbFileRead.getInputStream();
					byte[] buffer = new byte[4096];
					int len = 0;
					while ((len = in.read(buffer, 0, buffer.length)) != -1) {
						bos.write(buffer, 0, len);
					}
					
					bos.flush();
					bos.close();
					
					System.out.println("檔案下載成功");
					System.out.println("==========================");
				} else {
					System.out.println("檔案不存在");
				}
            }
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (client != null) {
				client.close();
			}
		}
	}
}