
今天的越寫悅快樂之系列文章為大家?guī)鞸pring Boot項(xiàng)目如何連接Samba服務(wù)。作為一名愛做夢的碼農(nóng)來說,探索未知的領(lǐng)域并應(yīng)用是我們不懈的追求,當(dāng)然這些應(yīng)用也需要建立在特定的場景下才能發(fā)揮潛能,也更能通過產(chǎn)品或服務(wù)滿足客戶的需求,接下來我們通過Samba來構(gòu)建我們的文件服務(wù),通過它可以快速讀寫文件,接下來讓我們來看看。
Samba是一個(gè)應(yīng)用于Linux和Unix的Windows應(yīng)用程序套件,它為所有使用SMB/CIFS協(xié)議的客戶機(jī)提供了安全、穩(wěn)定和快速的文件和打印服務(wù)。
開發(fā)環(huán)境
- Window 10.0.17763
- IntelliJ IDEA 2019.1
- Spring Boot 2.3.7
創(chuàng)建Samba服務(wù)
為了能快速創(chuàng)建Samba服務(wù),我們在Linux主機(jī)上使用Docker來進(jìn)行相關(guān)操作
Linux下Docker的安裝請自行搜索
拉取鏡像
我們通過SSH連接Linux服務(wù)器,然后在終端軟件Xshell中執(zhí)行以下命令:
docker pull dperson/samba
創(chuàng)建映射目錄
mkdir -p /home/docker/samba/data
啟動(dòng)鏡像
在啟動(dòng)容器的時(shí)候需要指定工作目錄、連接Samba的賬號和密碼、映射目錄的讀寫規(guī)則,具體的啟動(dòng)命令如下:
docker run -it --name samba -p 139:139 -p 445:445 -v /home/docker/samba/data:/home/shares/shareA -d dperson/samba -w "WORKGROUP" -u "smbuser;123456789" -s "shareA;/home/shares/shareA;yes;no;no;smbuser;smbuser;smbuser"
可以通過
docker ps -a查看Samba容器服務(wù)是否啟動(dòng)
接入步驟
創(chuàng)建項(xiàng)目
我們使用IntelliJ IDEA創(chuàng)建項(xiàng)目samba-tour,然后引入jcifs依賴,Maven的配置文件參考以下內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>me.weitao.app</groupId>
<artifactId>samba-tour</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>samba-tour</name>
<description>Samba Tour for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<jcifs.version>2.1.22</jcifs.version>
</properties>
<repositories>
<repository>
<id>AliYun Nexus</id>
<name>AliYun Nexus</name>
<url>https://maven.aliyun.com/nexus/content/repositories/central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>AliYun Nexus</id>
<name>AliYun Nexus</name>
<url>https://maven.aliyun.com/nexus/content/repositories/central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.codelibs/jcifs -->
<dependency>
<groupId>org.codelibs</groupId>
<artifactId>jcifs</artifactId>
<version>${jcifs.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
編寫測試文件
隨后我們查看一下項(xiàng)目的結(jié)果,如下圖所示:

在SambaTourApplicationTests文件中編寫讀寫文件的函數(shù),可參考一下內(nèi)容:
package me.weitao.app;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileInputStream;
import jcifs.smb.SmbFileOutputStream;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.*;
@SpringBootTest
@Slf4j
class SambaTourApplicationTests {
public static void smbGet(String remoteUrl, String localDir) {
System.out.println("進(jìn)入 smbGet() ....");
InputStream in = null;
OutputStream out = null;
try {
SmbFile remoteFile = new SmbFile(remoteUrl);
System.out.println(remoteFile.exists());
System.out.println(remoteFile.canRead());
System.out.println(remoteFile.canWrite());
System.out.println("嘗試連接 遠(yuǎn)程文件 ....");
if (remoteFile.exists()) {
log.info("找到文件....");
String fileName = remoteFile.getName();
File localFile = new File(localDir + "\\" + fileName);
in = new BufferedInputStream(new SmbFileInputStream(remoteFile));
out = new BufferedOutputStream(new FileOutputStream(localFile));
byte[] buffer = new byte[1024];
while (in.read(buffer) != -1) {
out.write(buffer);
buffer = new byte[1024];
}
} else {
log.info(remoteUrl + "文件不存在!");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void smbPut(String remoteUrl, String localFilePath) {
InputStream in = null;
OutputStream out = null;
try {
File localFile = new File(localFilePath);
String fileName = localFile.getName();
SmbFile remoteFile = new SmbFile(remoteUrl + "/" + fileName);
in = new BufferedInputStream(new FileInputStream(localFile));
out = new BufferedOutputStream(new SmbFileOutputStream(remoteFile));
byte[] buffer = new byte[1024];
while (in.read(buffer) != -1) {
out.write(buffer);
buffer = new byte[1024];
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
out = null;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
void contextLoads() {
// smbGet("smb://smbuser:123456789@192.168.8.192/shareA/def.txt", "F:/shareA");
// smbPut("smb://smbuser:123456789@192.168.8.192/shareA", "F:\\shareA\\def.txt");
}
}
shareA是我們Docker啟動(dòng)時(shí)的映射路徑
smbuser:123456789是我們連接Samba的賬號和密碼
192.168.8.192是我們的Linux主機(jī)的IP地址
創(chuàng)建測試文件
在執(zhí)行測試函數(shù)之前,我們需要在shareA目錄下創(chuàng)建文件def.txt,并寫入以下內(nèi)容:
welcome to samba
查看結(jié)果
隨后我們執(zhí)行測試函數(shù),調(diào)用smbPut方法并傳入需要連接的Samba信息,以及本地文件路徑,執(zhí)行結(jié)果如下圖所示:

驗(yàn)證結(jié)果
隨后我們按下Windows + R并輸入\\192.168.8.192,如果出現(xiàn)你不能訪問此共享文件夾,因?yàn)槟憬M織的安全策略阻止未經(jīng)身份驗(yàn)證的來賓訪問的警告,請參考這篇文章來解決,隨后我們再次輸入\\192.168.8.192提示我們輸入身份驗(yàn)證信息,輸入我們在Samba容器啟動(dòng)時(shí)配置的賬號和密碼,在shareA目錄中可以看到剛才執(zhí)行測試的文件了。

參考
個(gè)人收獲及總結(jié)
文件系統(tǒng)作為一個(gè)產(chǎn)品的常用服務(wù),可以快速搭建基礎(chǔ)服務(wù),當(dāng)然這些基礎(chǔ)設(shè)施需要我們根據(jù)實(shí)際業(yè)務(wù)去梳理和調(diào)整,通過不斷地優(yōu)化和打磨才能讓我們的產(chǎn)品和服務(wù)更上一層樓,也希望我們能為互聯(lián)網(wǎng)的發(fā)展貢獻(xiàn)自己的一份力量,讓我們一起構(gòu)建自己的核心競爭力。若是我的文章對你有所啟發(fā),那將是我莫大的榮幸。希望和您一起精進(jìn),成為更好的自己。