Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.alogic.vfs.sftp.SFtp Maven / Gradle / Ivy
package com.alogic.vfs.sftp;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.alogic.terminal.sshj.Authenticator;
import com.alogic.vfs.core.VirtualFileSystem;
import com.anysoft.util.IOTools;
import com.anysoft.util.Properties;
import com.anysoft.util.PropertiesConstants;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.sftp.*;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
import net.schmizz.sshj.xfer.FilePermission;
/**
* 基于sftp的vfs
*
* @author weibj
* @version 1.6.7.9 [20170201 duanyy]
* - 采用SLF4j日志框架输出日志
*
* @version 1.6.7.11 [20170203 duanyy]
* - 增加toString实现
*
* @version 1.6.7.13 [20170206 duanyy]
* - 写文件接口增加permissions参数,以便在创建文件时指定文件的权限
*
* @version 1.6.7.18 [20170227 duanyy]
* - 修正SFtp的java.lang.NegativeArraySizeException异常
*
* @version 1.6.9.3 [20170615 duanyy]
* - 增加move的方法
*
* @version 1.6.9.4 [20170615 duanyy]
* - 统一各实现的文件名匹配规则为正则表达式匹配
*
* @version 1.6.12.44 [20191023 duanyy]
* - 增加支持证书登录
*/
public class SFtp extends VirtualFileSystem.Abstract {
protected SSHClient sshClient = null;
protected SFTPClient sftpClient = null;
/*
* sftp的主机
*/
protected String host;
/*
* sftp的端口号
*/
protected int port = 22;
/*
* 创建目录的权限值
*/
protected int permissions = 0777;
private static int ONCE_MAX_BYTES = 32768;
protected Authenticator authenticator = null;
public SFtp() {
}
@Override
public String toString(){
return String.format("%s[sftp://%s:%d%s]",id,host,port,root);
}
@Override
public void configure(Properties p) {
host = PropertiesConstants.getString(p, "host", host);
port = PropertiesConstants.getInt(p, "port", port);
id = PropertiesConstants.getString(p, "id", "default", true);
dftPattern = PropertiesConstants.getString(p, "dftPattern", "[.]*[^.]+.*");
root = PropertiesConstants.getString(p, "root", root);
permissions = PropertiesConstants.getInt(p, "permissions", permissions);
Authenticator.TheFactory factory = new Authenticator.TheFactory();
try{
authenticator = factory.newInstance(PropertiesConstants.getString(p, "auth", "WithPassword"),p);
}catch (Exception ex){
LOG.error("Can not create authenticator.");
}
}
protected SFTPClient getClient() {
if (sftpClient == null) {
synchronized (this) {
if (sftpClient == null) {
try {
sshClient = new SSHClient();
sshClient.addHostKeyVerifier(new PromiscuousVerifier());
sshClient.connect(this.host,this.port);
if (authenticator != null){
authenticator.authenticate(sshClient);
}
sftpClient = sshClient.newSFTPClient();
} catch (Exception e) {
LOG.error(e.getMessage());
}
}
}
}
return sftpClient;
}
protected void getFileInfo(FileAttributes attrs, Map json) {
json.put("dir", attrs.getType() == FileMode.Type.DIRECTORY);
json.put("lastModified", attrs.getMtime());
json.put("lastAccess", attrs.getAtime());
json.put("length", attrs.getSize());
json.put("symLink", attrs.getType() == FileMode.Type.SYMLINK);
json.put("groupId", attrs.getGID());
json.put("permission", Integer.toOctalString(FilePermission.toMask(attrs.getPermissions())));
json.put("ownerId", attrs.getUID());
}
@Override
protected String getRealPath(String path) {
return root + File.separatorChar + path;
}
@Override
public List listFiles(String path, String pattern, int offset, int limit) {
List result = new ArrayList();
SFTPClient client = getClient();
String realPath = getRealPath(path);
try {
if (isDir(path)) {
List files = client.ls(realPath);
if (files != null) {
Pattern p = Pattern.compile(pattern);
int current = 0;
for (int i = 0; i < files.size(); i++) {
RemoteResourceInfo entry = files.get(i);
String filename = entry.getName();
Matcher matcher = p.matcher(filename);
if (matcher.matches()) {
if (current >= offset) {
result.add(filename);
}
current++;
if (current >= offset + limit) {
break;
}
}
}
}
}
} catch (IOException e) {
LOG.error(e.getMessage());
}
return result;
}
@Override
public void listFiles(String path, String pattern, Map json, int offset, int limit) {
SFTPClient client = getClient();
String realPath = getRealPath(path);
try {
if (isDir(path)) {
List result = new ArrayList();
List files = client.ls(realPath);
if (files != null) {
Pattern p = Pattern.compile(pattern);
int current = 0;
for (int i = 0; i < files.size(); i++) {
RemoteResourceInfo file = files.get(i);
String filename = file.getName();
Matcher matcher = p.matcher(filename);
if (matcher.matches()) {
if (current >= offset) {
Map map = new HashMap();
getFileInfo(file.getAttributes(), map);
map.put("name", filename);
map.put("path", path + File.separator + filename);
result.add(map);
}
current++;
if (current >= offset + limit) {
break;
}
}
}
json.put("file", result);
json.put("offset", offset);
json.put("limit", limit);
json.put("total", current);
json.put("path", path);
}
}
} catch (IOException e) {
LOG.error(e.getMessage());
}
}
@Override
public boolean deleteFile(String path) {
SFTPClient client = getClient();
String realPath = getRealPath(path);
try {
if (isDir(path)) {
deleteFolder(path);
client.rmdir(getRealPath(path));
} else {
client.rm(realPath);
}
return true;
} catch (IOException e) {
LOG.error(e.getMessage());
return false;
}
}
//递归删除文件夹
private Boolean deleteFolder(String folderPath) {
Boolean result = true;
SFTPClient client = getClient();
List fileLists = new ArrayList();
fileLists = listFiles(folderPath, dftPattern, 0, Integer.MAX_VALUE);
for (String file : fileLists) {
try {
String path = folderPath + File.separatorChar + file;
if (isDir(path)) {
deleteFolder(path);
client.rmdir(getRealPath(path));
} else {
client.rm(getRealPath(path));
}
} catch (IOException e) {
LOG.error(e.getMessage());
result = false;
}
}
return result;
}
@Override
public boolean exist(String path) {
SFTPClient client = getClient();
path = getRealPath(path);
try {
client.stat(path);
} catch (Exception e) {
return false;
}
return true;
}
@Override
public boolean isDir(String path) {
SFTPClient client = getClient();
path = getRealPath(path);
try {
FileAttributes attrs = client.stat(path);
return attrs == null ? false : (attrs.getType()==FileMode.Type.DIRECTORY);
} catch (IOException e) {
LOG.error(e.getMessage());
return false;
}
}
@Override
public long getFileSize(String path) {
SFTPClient client = getClient();
path = getRealPath(path);
try {
FileAttributes attrs = client.stat(path);
return attrs == null ? 0 : attrs.getSize();
} catch (IOException e) {
LOG.error(e.getMessage());
return 0;
}
}
@Override
public void getFileInfo(String path, Map json) {
SFTPClient client = getClient();
path = getRealPath(path);
try {
FileAttributes attrs = client.stat(path);
if (attrs != null) {
getFileInfo(attrs, json);
json.put("path", path);
}
} catch (IOException e) {
LOG.error(e.getMessage());
}
}
@Override
public boolean makeDirs(String path) {
SFTPClient client = getClient();
String arrPath[] = path.split(File.separatorChar + "");
String pathtmp = "";
for (int i = 0; i < arrPath.length; i++) {
pathtmp += File.separatorChar + arrPath[i];
try {
if (!isDir(pathtmp)) {
client.mkdir(getRealPath(pathtmp));
}
} catch (IOException e) {
LOG.error(e.getMessage());
return false;
}
}
return true;
}
private byte[] byteMerger(byte[] byte_1, byte[] byte_2) {
byte[] byte_3 = new byte[byte_1.length + byte_2.length];
System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length);
System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length);
return byte_3;
}
@Override
public InputStream readFile(String path) {
SFTPClient client = getClient();
String realPath = getRealPath(path);
int startid = 0;
try {
if (!isDir(path)) {
RemoteFile file = client.open(realPath);
return file.new RemoteFileInputStream();
}
return null;
} catch (IOException e) {
LOG.error(e.getMessage());
return null;
}
}
@Override
public void finishRead(String path, InputStream in) {
IOTools.close(in);
}
@Override
public OutputStream writeFile(String path, int permissions) {
final SFTPClient client = getClient();
String realPath = getRealPath(path);
try {
if (!exist(path)) {
RemoteFile file = client.open(realPath,
EnumSet.of(OpenMode.WRITE, OpenMode.CREAT, OpenMode.TRUNC));
return file.new RemoteFileOutputStream();
}
return null;
} catch (IOException e) {
LOG.error(e.getMessage());
return null;
}
}
@Override
public OutputStream writeFile(String path) {
return writeFile(path,0755);
}
@Override
public void finishWrite(String path, OutputStream out) {
IOTools.close(out);
}
@Override
public void close() {
if (sftpClient != null) {
IOTools.close(sftpClient);
}
if (sshClient != null) {
IOTools.close(sshClient);
}
}
@Override
public boolean move(String src, String dest, boolean overwrite) {
String srcPath = getRealPath(src);
String destPath = getRealPath(dest);
if (!this.exist(srcPath)){
//源路径不存在
return false;
}
if (this.exist(destPath)){
if (!overwrite){
return false;
}
this.deleteFile(destPath);
}
try {
SFTPClient client = getClient();
client.rename(srcPath, destPath);
return true;
} catch (IOException e) {
return false;
}
}
}