1.添加依赖:
gradle工程:
implementation 'org.codelibs:jcifs:2.1.31'
maven工程:
<dependency>
<groupId>org.codelibs</groupId>
<artifactId>jcifs</artifactId>
<version>2.1.31</version>
</dependency>
2.获取Smb对象:
类:SmbFile( String url, NtlmPasswordAuthentication auth )
url: 以"smb://"开头
NtlmPasswordAuthentication : windows用户凭证,由于域名,用户名,密码作为参数创建
SmbFile smbFile = new SmbFile("smb://192.168.1.1/share/", new NtlmPasswordAuthentication(domain, "userName", "password"));
3.枚举smb://192.168.1.1/share/下的所有文件及目录:
SmbFile[] files = smbFile.listFile();
4.从Windows共享目录中读取文件:SmbReader.java
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import jcifs.smb1.smb1.NtlmPasswordAuthentication;
import jcifs.smb1.smb1.SmbFile;
import jcifs.smb1.smb1.SmbFileInputStream;
public class SmbReader {
static final String TAG_SMB_READER = "SMB_READER";
static final int DEFAULT_BUFFER_SIZE = 524288; // 512 Kb
final NtlmPasswordAuthentication authentication;
public SmbReader(NtlmPasswordAuthentication authentication) {
this.authentication = authentication;
}
public SmbReader(String user, String password) {
this(null, user, password);
}
public SmbReader(String domain, String user, String password) {
this.authentication = new NtlmPasswordAuthentication(domain, user, password);
}
/**
* read windows share object and save to local
* @param url url of object, format: "smb://host/path/", such as "smb://192.168.1.2/share/"
* @param localPath local path(android)
* @param overwrite overwrite
* @param excludeHideFiles exclude hide files
* @return true | false
*/
public boolean read(String url, String localPath, boolean overwrite, boolean excludeHideFiles) {
boolean result = false;
try {
if (url.isEmpty() || localPath.isEmpty()) {
Log.e(TAG_SMB_READER,"method: read, params error");
return false;
}
SmbFile srcFile = new SmbFile(url, this.authentication);
if (srcFile == null || !srcFile.exists()) {
Log.e(TAG_SMB_READER,"method: read, the smb file is not exist");
return false;
}
result = read(srcFile, localPath, overwrite, excludeHideFiles);
} catch (Exception e) {
Log.e(TAG_SMB_READER, "method: save, exception: " + e.getMessage());
}
return result;
}
private boolean read(SmbFile srcFile, String localPath, boolean overwrite, boolean excludeHideFiles) {
try {
File file = new File(localPath + File.separator + srcFile.getName());
if (file.getParentFile() != null && !file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
if (srcFile.isDirectory()) {
if (!file.exists()) {
file.mkdirs();
}
SmbFile[] subSmbFiles = excludeHideFiles ? srcFile.listFiles(file1 -> !file1.isHidden()) : srcFile.listFiles();
for (SmbFile subSmbFile: subSmbFiles) {
read(subSmbFile, file.getPath(), overwrite, excludeHideFiles);
}
} else if (srcFile.isFile()) {
if (overwrite && file.exists()) {
file.delete();
}
if (!read(srcFile, file)) {
return false;
}
}
} catch (Exception e) {
Log.e(TAG_SMB_READER, "method: save, exception: " + e.getMessage());
return false;
}
return true;
}
private boolean read(SmbFile smbFile, File file) {
boolean result = true;
try (InputStream in = new BufferedInputStream(new SmbFileInputStream(smbFile));
OutputStream out = new BufferedOutputStream(new FileOutputStream(file))) {
if (smbFile.length() > 0) {
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int read = 0;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
out.flush();
} else if (smbFile.length() == 0) {
file.createNewFile();
}
} catch (Exception e) {
Log.e(TAG_SMB_READER, "method: saveFile, exception: " + e.getMessage());
result = false;
}
return result;
}
}
用法:
// read file/folder from windows share folder
String url = "smb://192.168.1.2/share/hello.docx";
SmbReader reader = new SmbReader("userName", "password");
boolean result = reader.read(url, path, true, true);
if (result) {
Log.i(TAG_MAIN_FRAGMENT, "read smb file object success");
}
5.往windows共享目录写文件:SmbWriter.java
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import jcifs.smb1.smb1.NtlmPasswordAuthentication;
import jcifs.smb1.smb1.SmbFile;
import jcifs.smb1.smb1.SmbFileOutputStream;
public class SmbWriter {
static final String TAG_SMB_WRITER = "SMB_WRITER";
static final int DEFAULT_BUFFER_SIZE = 524288; // 512 Kb
final NtlmPasswordAuthentication authentication;
public SmbWriter(NtlmPasswordAuthentication authentication) {
this.authentication = authentication;
}
public SmbWriter(String user, String password) {
this(null, user, password);
}
public SmbWriter(String domain, String user, String password) {
this.authentication = new NtlmPasswordAuthentication(domain, user, password);
}
/**
* write file/folder to windows share dir
* @param srcPath local resource path, file or folder
* @param url target path(only folder path), format: "smb://host/path/", file: "smb://192.168.1.2/share/"
* @param overwrite overwrite
* @param excludeHideFiles exclude hide files
* @return
*/
public boolean write(String srcPath, String url, boolean overwrite, boolean excludeHideFiles) {
boolean result = false;
try {
File file = new File(srcPath);
if (!file.exists()) {
Log.e(TAG_SMB_WRITER, "method: write, resource isn't exist or params error");
return false;
}
url = url + File.separator + file.getName();
SmbFile smbFile = new SmbFile(url, this.authentication);
if (file.isDirectory()) {
if (!smbFile.exists()) {
smbFile.mkdirs();
}
File[] subFiles = excludeHideFiles ? file.listFiles(subFile -> !subFile.isHidden()) : file.listFiles();
for (File subFile : subFiles) {
String subSrcPath = srcPath + File.separator + subFile.getName();
write(subSrcPath, url, overwrite, excludeHideFiles);
}
} else if (file.isFile()) {
if (smbFile.exists() && overwrite) {
smbFile.delete();
}
result = writeFile(file, smbFile);
}
} catch (Exception e) {
Log.e(TAG_SMB_WRITER, "method: write, exception: " + e.getMessage());
}
return result;
}
public boolean writeFile(File file, SmbFile smbFile) {
boolean result = false;
try (InputStream in = new BufferedInputStream(new FileInputStream(file));
OutputStream out = new BufferedOutputStream(new SmbFileOutputStream(smbFile));) {
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
out.flush();
result = true;
} catch (Exception e) {
Log.e(TAG_SMB_WRITER, "method: writeFile, write file failed, exception: " + e.getMessage());
}
return result;
}
}
用法:
// write file/folder to windows share
String url = "smb://192.168.1.2/share/";
SmbWriter writer = new SmbWriter("userName", "password");
boolean result = writer.write(path, url, true, true);
if (result) {
Log.i(TAG_MAIN_FRAGMENT, "write smb file object success");
}