SftpClientHandler.java 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. package com.primeton.damp.fileclient;
  2. import com.google.common.collect.Lists;
  3. import org.apache.sshd.client.subsystem.sftp.fs.SftpFileSystemProvider;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.io.OutputStream;
  9. import java.nio.file.DirectoryStream;
  10. import java.nio.file.FileSystem;
  11. import java.nio.file.FileSystemAlreadyExistsException;
  12. import java.nio.file.FileSystems;
  13. import java.nio.file.Files;
  14. import java.nio.file.Path;
  15. import java.nio.file.StandardOpenOption;
  16. import java.util.Collections;
  17. import java.util.List;
  18. import java.util.Map;
  19. import java.util.Properties;
  20. import static java.nio.file.StandardOpenOption.APPEND;
  21. import static java.nio.file.StandardOpenOption.CREATE;
  22. /**
  23. * Created by hadoop on 2018/8/9.
  24. */
  25. public class SftpClientHandler implements X11ClientHandler {
  26. protected static Logger logger = LoggerFactory.getLogger("SftpClientHandler");
  27. private final String sftpHost;
  28. private final int sftpPort;
  29. private final String ftpUsername;
  30. private final String ftpPassword;
  31. /**
  32. * sftp 文件系统
  33. */
  34. FileSystem fs;
  35. public SftpClientHandler(String host,
  36. int port,
  37. String username,
  38. String password,
  39. Properties params) {
  40. sftpHost = host;
  41. sftpPort = port;
  42. ftpUsername = username;
  43. ftpPassword = password;
  44. this.reconnect(params);
  45. }
  46. /**
  47. * 以账号和密码重新连接
  48. * @param params
  49. */
  50. @Override
  51. public void reconnect(Properties params) {
  52. java.net.URI uri = SftpFileSystemProvider.createFileSystemURI(this.sftpHost, sftpPort, ftpUsername, ftpPassword);
  53. try {
  54. fs = FileSystems.newFileSystem(uri, (Map) params);
  55. } catch (FileSystemAlreadyExistsException e){
  56. logger.warn("exists file system sftp...");
  57. fs = FileSystems.getFileSystem(uri);
  58. } catch (IOException e) {
  59. logger.error("ftp connect is error.", e);
  60. throw new IllegalStateException("can not connect sftp: " + sftpHost+":"+ sftpPort);
  61. }
  62. }
  63. /**
  64. * 写文件流
  65. * @param file
  66. * @return
  67. * @throws IOException
  68. */
  69. @Override
  70. public OutputStream writeFile(String file, boolean overwrite) throws IOException {
  71. Path path1 = fs.getPath(file);
  72. if(overwrite) {
  73. return Files.newOutputStream(path1, CREATE);
  74. } else {
  75. return Files.newOutputStream(path1, APPEND);
  76. }
  77. }
  78. /**
  79. * 读取文件流
  80. * @param file
  81. * @return
  82. * @throws IOException
  83. */
  84. @Override
  85. public InputStream readFile(String file) throws IOException {
  86. Path path1 = fs.getPath(file);
  87. return Files.newInputStream(path1, StandardOpenOption.READ);
  88. }
  89. @Override
  90. public boolean rename(String file, String newFileName) {
  91. try {
  92. Path path1 = fs.getPath(file);
  93. Path path = fs.getPath(path1.getParent().toString(), newFileName);
  94. Files.move(path1, path);
  95. logger.info("rename {} to {}", path1.toString(), path.toString());
  96. return true;
  97. } catch (Exception e) {
  98. logger.error("Error in rename ftp file.", e);
  99. return false;
  100. }
  101. }
  102. /**
  103. * 删除文件, 返回 true 则删除成功
  104. * @param path
  105. */
  106. public boolean deleteFile(String path) {
  107. final Path fsPath = fs.getPath(path);
  108. try {
  109. if (Files.exists(fsPath) && Files.isDirectory(fsPath)) {
  110. // 删除文件夹,连带文件夹一起删除,包括其下的子文件
  111. Files.list(fsPath).forEach(it-> deleteFile(it.toString()));
  112. Files.delete(fsPath);
  113. logger.info("delete dir: {}", path);
  114. } else {
  115. // 删除文件
  116. Files.delete(fsPath);
  117. logger.info("delete file: {}", path);
  118. }
  119. } catch (Exception e) {
  120. throw new RuntimeException(e);
  121. }
  122. return true;
  123. }
  124. /**
  125. * 判断目录是否存在
  126. * @param path
  127. * @return
  128. */
  129. @Override
  130. public boolean existsDir(String path) {
  131. try {
  132. Path path1 = fs.getPath(path);
  133. return Files.exists(path1) && Files.isDirectory(path1);
  134. } catch (Exception e) {
  135. }
  136. return false;
  137. }
  138. /**
  139. * 判断目录是否存在
  140. * @param path
  141. * @return
  142. */
  143. @Override
  144. public boolean existsFile(String path) {
  145. try {
  146. Path path1 = fs.getPath(path);
  147. return Files.exists(path1) && Files.isRegularFile(path1);
  148. } catch (Exception e) {
  149. }
  150. return false;
  151. }
  152. /**
  153. * 判断目录或者文件是否存在
  154. * @param path
  155. * @return
  156. */
  157. @Override
  158. public boolean exists(String path) {
  159. try {
  160. Path path1 = fs.getPath(path);
  161. return Files.exists(path1);
  162. } catch (Exception e) {
  163. }
  164. return false;
  165. }
  166. /**
  167. * 创建多层目录
  168. * @param path
  169. * @return
  170. */
  171. @Override
  172. public boolean mkdirs(String path) {
  173. Path path1 = fs.getPath(path);
  174. Path parentPath = path1.getParent();
  175. if(parentPath == null) {
  176. // parentPath 等于 null 则说明是文件系统的根目录了。
  177. return true;
  178. }
  179. // 父级目录已经存在,只创建当前目录
  180. if(existsDir(parentPath.toString())){
  181. return mkdir(path1.toString()); // 创建当前文件夹
  182. } else {
  183. // 父级目录不存在,则先创建父级目录,再创建当前目录
  184. if(mkdirs(parentPath.toString())) { // 创建父级目录
  185. return mkdir(path1.toString()); // 创建当前文件夹
  186. }
  187. }
  188. // 最后创建文件夹肯定是不成功的。
  189. return existsDir(path);
  190. }
  191. /**
  192. * 创建目录, 返回 true 则创建目录成功
  193. * @param dirName 一级或者多级目录
  194. */
  195. @Override
  196. public boolean mkdir(String dirName) {
  197. try {
  198. Path path1 = fs.getPath(dirName);
  199. Files.createDirectory(path1);
  200. return true;
  201. } catch (IOException e) {
  202. logger.info("mkdir " + dirName + " fail.", e);
  203. }
  204. return false;
  205. }
  206. /**
  207. * 获取一个目录下或者文件的子文件
  208. * @param ftpPath
  209. * @return
  210. */
  211. @Override
  212. public List<Path> getChildren(String ftpPath) {
  213. Path remotePath = fs.getPath(ftpPath);
  214. try {
  215. DirectoryStream<Path> paths = Files.newDirectoryStream(remotePath);
  216. return Lists.newArrayList(paths.iterator());
  217. } catch (IOException e) {
  218. logger.info("Error in scan sftpfile.");
  219. }
  220. return Collections.emptyList();
  221. }
  222. @Override
  223. public void close() throws IOException {
  224. logger.warn("close the file system");
  225. fs.close();
  226. }
  227. }