使用SMBJ协议上传文件到windows文件夹

使用SMBJ协议远程传输文件到共享文件夹

SMBJ概述
SMB(Server Message Block)通信协议是微软(Microsoft)和英特尔(Intel)在1987年制定的协议,主要是作为Microsoft网络的通讯协议。SMB 是在会话层(session layer)和表示层(presentation layer)以及小部分应用层(application layer)的协议。

SMBJ的版本问题

随着windows版本的升级,SMBJ的版本也从最初的SMBJ1.0到现在的SMBJ3.0,其安全性也是不断的提高。SMBJ1.0存在较大的安全问题,具体你可以自己了解一下,以下是各个windows版本跟smbj协议的对照表
在这里插入图片描述

使用SMBJ协议上传文件到远程文件夹

如果你的远程文件夹的windows系统版本较为古老,Windows2003或者其他的,你需要使用jcifs jar包上传文件,在对应的pom文件加入以下依赖

<dependency>
            <groupId>jcifs</groupId>
            <artifactId>jcifs</artifactId>
            <version>1.2.25</version>
</dependency>

如果windows系统支持SMBJ2.0或以上的版本,你可以使用smbj jar包上传

<dependency>
            <groupId>com.hierynomus</groupId>
            <artifactId>smbj</artifactId>
            <version>0.10.0</version>
 </dependency>

同时使用这两个jar包,就可以支持到不同的版本的SMBJ协议。

代码示例

以下是我jcifs+smbj上传文件的示例,第一个try是尝试使用smbj协议上传文件,如果失败的话,在catch中使用jcifs尝试上传。具体可以看代码,当然得保证连接服务器的信息正确。

import com.hierynomus.msdtyp.AccessMask;
import com.hierynomus.msfscc.FileAttributes;
import com.hierynomus.msfscc.fileinformation.FileIdBothDirectoryInformation;
import com.hierynomus.mssmb2.SMB2CreateDisposition;
import com.hierynomus.mssmb2.SMB2CreateOptions;
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;
import jcifs.smb.SmbException;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileOutputStream;

import java.io.*;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/*
 * https://www.javadoc.io/static/com.hierynomus/smbj/0.10.0/com/hierynomus/smbj/SMBClient.html
 * */
public class SmbjTest {

    static void uploadFile2(String hostname, String username, String password, String domain, String folderName){
        String localFile = "D:\\1.xlsx"; // 本地要上传的文件

        SmbConfig config = SmbConfig.builder()
                .withTimeout(120, TimeUnit.SECONDS) // Timeout sets Read, Write, and Transact timeouts (default is 60 seconds)
                .withSoTimeout(180, TimeUnit.SECONDS) // Socket Timeout (default is 0 seconds, blocks forever)
                .build();

        SMBClient client = new SMBClient(config);
        try (Connection connection = client.connect(hostname)) {
            AuthenticationContext ac = new AuthenticationContext(username, password.toCharArray(), domain);
            Session session = connection.authenticate(ac);

            try (DiskShare share = (DiskShare) session.connectShare(folderName)) {
                System.out.println("connect smbj success");
                Set<AccessMask> accessMasks = new HashSet<>();
                accessMasks.add(AccessMask.FILE_ADD_FILE);
                Set<FileAttributes> attributes = new HashSet<>();
                attributes.add(FileAttributes.FILE_ATTRIBUTE_NORMAL);
                Set<SMB2ShareAccess> smb2ShareAccesses= new HashSet<>();
                smb2ShareAccesses.add(SMB2ShareAccess.FILE_SHARE_WRITE);
                Set<SMB2CreateOptions> smb2CreateOptions= new HashSet<>();
                smb2CreateOptions.add(SMB2CreateOptions.FILE_RANDOM_ACCESS);

//                System.out.println(1234);
                File openFile = share.openFile("5.xlsx", accessMasks, attributes, smb2ShareAccesses, SMB2CreateDisposition.FILE_OVERWRITE_IF, smb2CreateOptions);
                OutputStream oStream = openFile.getOutputStream();
                BufferedInputStream in = new BufferedInputStream(new FileInputStream(localFile));

                byte[] buffer = new byte[1024];
                int len = 0; //Read length
                while ((len = in.read(buffer, 0, buffer.length)) != -1) {
                    oStream.write(buffer, 0, len);
                }
                oStream.flush();
                oStream.close();
                System.out.println("open file");

            }catch (Exception e){
                System.out.println("err1");
                e.printStackTrace();
            }

        } catch (Exception e) {
            System.out.println("connect smbj fail");
            System.out.println(e.getMessage());

            System.out.println("try to connect jcifs.... ");
            String url = "smb://"+username+":"+password+"@"+hostname+"/"+folderName;
            try{
                SmbFile smbFile = new SmbFile(url);
                smbFile.connect();
                System.out.println("jcifs connect successful");
                java.io.File file = new java.io.File(localFile);
                try {
                    int flag =-1;
                    System.out.println(url + "/"
                            + file.getName());
                    SmbFileOutputStream smbOut = new SmbFileOutputStream(url + "/"
                            + file.getName(), false);
                    BufferedInputStream bf = new BufferedInputStream(new FileInputStream(file));
                    byte[] bt = new byte[1024];
                    int n = bf.read(bt);
                    while (n != -1) {
                        smbOut.write(bt, 0, n);
                        smbOut.flush();
                        n = bf.read(bt);
                    }
                    flag = 0;
                    System.out.println("文件传输结束...");
                } catch (SmbException smbException) {
                    e.printStackTrace();
                    System.out.println(smbException);
                }
            }catch (Exception smbException){
                smbException.printStackTrace();
            }

        }
    }

    /**
     * 把一个文件转化为byte字节数组。
     *
     * @return
     */
    private static byte[] fileConvertToByteArray(java.io.File file) {
        byte[] data = null;

        try {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            int len;
            byte[] buffer = new byte[1024];
            while ((len = fis.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }

            data = baos.toByteArray();

            fis.close();
            baos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    public static void main(String[] args) {
        SmbjTest.uploadFile2("hostname", "username", "password", "domain", "folderName");
    }
}

相关文档

SMBJ协议的错误码解析:https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/8f11e0f3-d545-46cc-97e6-f00569e3e1bc?redirectedfrom=MSDN
SMBJ协议版本信息:http://woshub.com/smb-1-0-support-in-windows-server-2012-r2/#!prettyPhoto

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值