• 读取服务器文件,并进行移动-ChannelSftp


    要求:

            读取服务器上某个目录的文件下的txt的内容,读取里面的数据,进行处理,保存入库。保存后,把文件移到该目录下的bak目录。

    处理:

            要操作服务器文件,需要使用 ChannelSftp,文档

    常用方法:

    put(): 文件上传
    get(): 文件下载
    cd(): 进入指定目录
    ls(): 得到指定目录下的文件列表
    rm(): 删除指定文件
    rename() 移动文件

    java代码:

    引用:

    1. gradle:
    2. // 添加sftp的工具包
    3. implementation group: 'com.jcraft', name: 'jsch', version: '0.1.55'
    4. maven:
    5. <dependency>
    6. <groupId>com.jcraft</groupId>
    7. <artifactId>jsch</artifactId>
    8. <version>0.1.55</version>
    9. </dependency>

    业务

    CustomerService

    1. @Slf4j
    2. @Service
    3. public class CustomerService {
    4. public void readFile() throws SftpException {
    5. SftpConfig sftpConfig = SftpUtils.getSftpConfigVal();
    6. ChannelSftp sftp = SftpUtils.connect(sftpConfig);
    7. String path = sftpConfig.getPath();
    8. String newpath = path + "/bak";
    9. // 判断文件路径是否存在
    10. SftpUtils.isExist(sftp, newpath);
    11. sftp.cd(path);
    12. // 读取txt文件
    13. Vector<ChannelSftp.LsEntry> list = sftp.ls("*.txt");
    14. List<String> data;
    15. String pathFileName, newpathFileName ="";
    16. for (ChannelSftp.LsEntry entry : list) {
    17. String fileName = entry.getFilename();
    18. log.info(fileName);
    19. pathFileName = path +"/"+ fileName;
    20. data = SftpUtils.getList(sftp, pathFileName);
    21. if(CollectionUtils.isNotEmpty(data)){
    22. Boolean moveFile = dealFileData(data);
    23. if(moveFile){
    24. try {
    25. newpathFileName = newpath + "/"+ fileName;
    26. log.info("path:{}, newPath: {} ", pathFileName, newpathFileName);
    27. sftp.rename(pathFileName, newpathFileName);
    28. }catch (Exception e){
    29. log.error("路径{},文件{}移动文件失败!", pathFileName, newpathFileName);
    30. e.printStackTrace();
    31. }
    32. }
    33. }
    34. }
    35. SftpUtils.disConnect(sftpConfig)
    36. }
    37. private Boolean dealFileData(List<String> data){
    38. Boolean moveFile = false;
    39. List<String> filterData = ListUtils.emptyIfNull(data).stream().filter(e -> e.contains("_")).collect(Collectors.toList());
    40. if(filterData.size() > 0){// 有符合要求的数据
    41. moveFile = true;
    42. // 对数据进行处理
    43. }
    44. return moveFile;
    45. }
    46. }

    实体:

    SftpConfig

    1. /**
    2. * sftp 配置
    3. */
    4. @Data
    5. public class SftpConfig {
    6. /** 密钥地址 */
    7. private String privateKeyPath;
    8. /** 口令 */
    9. private String passphrase;
    10. private String ip;
    11. private Integer port;
    12. private String username;
    13. private String pwd;
    14. private String path;
    15. private String baseDir;
    16. }

    SftpChannel

    1. @Slf4j
    2. public class SftpChannel {
    3. Session session = null;
    4. ChannelSftp sftp = null;
    5. //端口默认为22
    6. public static final int SFTP_DEFAULT_PORT = 22;
    7. /** 利用JSch包实现SFTP下载、上传文件(秘钥方式登陆)*/
    8. public ChannelSftp connectByIdentity(SftpConfig sftpConfig) throws JSchException {
    9. JSch jsch = new JSch();
    10. int port = SFTP_DEFAULT_PORT;
    11. //设置密钥和密码
    12. //支持密钥的方式登陆,只需在jsch.getSession之前设置一下密钥的相关信息就可以了
    13. if (StringUtils.isNotBlank(sftpConfig.getPrivateKeyPath())) {
    14. if (StringUtils.isNotBlank(sftpConfig.getPassphrase())) {
    15. //设置带口令的密钥
    16. jsch.addIdentity(sftpConfig.getPrivateKeyPath(), sftpConfig.getPassphrase());
    17. } else {
    18. //设置不带口令的密钥
    19. jsch.addIdentity(sftpConfig.getPrivateKeyPath());
    20. }
    21. }
    22. if (sftpConfig.getPort() != null) {
    23. port = sftpConfig.getPort();
    24. }
    25. if (port > 0) {
    26. //采用指定的端口连接服务器
    27. session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp(), port);
    28. } else {
    29. //连接服务器,采用默认端口
    30. session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp());
    31. }
    32. if (session == null) {
    33. throw new JSchException("session is null,connect fail");
    34. }
    35. log.info("Session created ... UserName={};ip={};port={}", sftpConfig.getUsername(), sftpConfig.getIp(), sftpConfig.getPort());
    36. Properties sshConfig = new Properties();
    37. sshConfig.put("StrictHostKeyChecking", "no");
    38. session.setConfig(sshConfig);
    39. session.setTimeout(30000);
    40. session.connect();
    41. //创建sftp通信通道
    42. Channel channel = session.openChannel("sftp");
    43. channel.connect();
    44. sftp = (ChannelSftp) channel;
    45. log.info("login success...");
    46. return sftp;
    47. }
    48. /** 利用JSch包实现SFTP下载、上传文件(用户名密码方式登陆) */
    49. public ChannelSftp connectByPwd(SftpConfig sftpConfig) throws JSchException {
    50. JSch jsch = new JSch();
    51. int port = SFTP_DEFAULT_PORT;
    52. if (sftpConfig.getPort() != null) {
    53. port = sftpConfig.getPort();
    54. }
    55. if (port > 0) {
    56. //采用指定的端口连接服务器
    57. session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp(), port);
    58. } else {
    59. //连接服务器,采用默认端口
    60. session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp());
    61. }
    62. if (session == null) {
    63. throw new JSchException("session is null,connect fail");
    64. }
    65. log.info("Session created ... UserName={};ip={};port={}", sftpConfig.getUsername(), sftpConfig.getIp(), sftpConfig.getPort());
    66. //设置登陆主机的密码
    67. session.setPassword(sftpConfig.getPwd());//设置密码
    68. Properties sshConfig = new Properties();
    69. sshConfig.put("StrictHostKeyChecking", "no");
    70. session.setConfig(sshConfig);
    71. session.setTimeout(30000);
    72. session.connect();
    73. //创建sftp通信通道
    74. Channel channel = session.openChannel("sftp");
    75. channel.connect();
    76. sftp = (ChannelSftp) channel;
    77. log.info("login success...");
    78. return sftp;
    79. }
    80. public void closeChannel() {
    81. log.info("sftp object closing...");
    82. if (sftp != null) {
    83. if (sftp.isConnected()) {
    84. sftp.disconnect();
    85. }
    86. }
    87. if (session != null) {
    88. if (session.isConnected()) {
    89. session.disconnect();
    90. }
    91. }
    92. }
    93. }

    工具类

    SftpUtils 

    1. /**
    2. * sftp 上传下载工具类
    3. */
    4. public class SftpUtils {
    5. private static Logger logger = LoggerFactory.getLogger(SftpUtils.class);
    6. private static long count = 3;
    7. private static long count1 = 0;
    8. private static long sleepTime;
    9. /**
    10. * 连接sftp服务器
    11. *
    12. * @return
    13. */
    14. public static ChannelSftp connect(SftpConfig sftpConfig) {
    15. ChannelSftp sftp = null;
    16. try {
    17. JSch jsch = new JSch();
    18. jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp(), sftpConfig.getPort());
    19. Session sshSession = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp(),
    20. sftpConfig.getPort());
    21. logger.info("Session created ... UserName=" + sftpConfig.getUsername() + ";host=" + sftpConfig.getIp()
    22. + ";port=" + sftpConfig.getIp());
    23. sshSession.setPassword(sftpConfig.getPwd());
    24. Properties sshConfig = new Properties();
    25. sshConfig.put("StrictHostKeyChecking", "no");
    26. sshSession.setConfig(sshConfig);
    27. sshSession.connect();
    28. logger.info("Session connected ...");
    29. logger.info("Opening Channel ...");
    30. Channel channel = sshSession.openChannel("sftp");
    31. channel.connect();
    32. sftp = (ChannelSftp) channel;
    33. logger.info("登录成功");
    34. } catch (Exception e) {
    35. try {
    36. count1 += 1;
    37. if (count == count1) {
    38. throw new RuntimeException(e);
    39. }
    40. if (count1 != count) {
    41. Thread.sleep(sleepTime);
    42. logger.info("connect again....");
    43. connect(sftpConfig);
    44. }
    45. } catch (InterruptedException e1) {
    46. e1.printStackTrace();
    47. throw new RuntimeException(e1);
    48. }
    49. }
    50. return sftp;
    51. }
    52. /**
    53. * 获取Sftp对象
    54. * @param param json sftp对象
    55. * @return SftpConfig
    56. */
    57. public static SftpConfig getSftpObj(String param) {
    58. SftpConfig sftpConfig = new SftpConfig();
    59. if (StringUtils.isNotBlank(param)) {
    60. sftpConfig = JSONObject.parseObject(param, SftpConfig.class);
    61. }
    62. return sftpConfig;
    63. }
    64. /** sftp 上传*/
    65. public static boolean upload(SftpConfig config, String baseDir, String fileName, String filePath) {
    66. logger.info("路径:baseDir=" + baseDir);
    67. SftpChannel sftpChannel = new SftpChannel();
    68. ChannelSftp sftp;
    69. try {
    70. if (StringUtils.isNotBlank(config.getPrivateKeyPath())) {
    71. sftp = sftpChannel.connectByIdentity(config);
    72. } else {
    73. sftp = sftpChannel.connectByPwd(config);
    74. }
    75. if (sftp.isConnected()) {
    76. logger.info("connect server success");
    77. } else {
    78. logger.error("connect server fail");
    79. return false;
    80. }
    81. //检查路径
    82. if (!isExist(sftp, baseDir)) {
    83. logger.error("创建sftp服务器路径失败:" + baseDir);
    84. return false;
    85. }
    86. String dst = baseDir + "/" + fileName;
    87. String src = filePath + "/" + fileName;
    88. logger.info("开始上传,本地服务器路径:[" + src + "]目标服务器路径:[" + dst + "]");
    89. sftp.put(src, dst);
    90. sftp.put(src, dst);
    91. logger.info("上传成功");
    92. return true;
    93. } catch (Exception e) {
    94. logger.error("上传失败", e);
    95. return false;
    96. } finally {
    97. sftpChannel.closeChannel();
    98. }
    99. }
    100. /** sftp 上传*/
    101. public boolean uploadNew(SftpConfig config, String baseDir, String fileName, ByteArrayOutputStream out) {
    102. logger.info("sftpconfig==>{}", config);
    103. ChannelSftp sftp = connect(config);
    104. boolean flag = true;
    105. try {
    106. sftp.cd(baseDir);
    107. logger.info("first step=========>{}");
    108. } catch (SftpException e) {
    109. try {
    110. sftp.mkdir(baseDir);
    111. sftp.cd(baseDir);
    112. } catch (SftpException e1) {
    113. flag = false;
    114. throw new RuntimeException("ftp create filepath fail" + baseDir);
    115. }
    116. }
    117. logger.info("the third step =========>{},uploadFile==>{}", flag, fileName);
    118. try (InputStream in = new ByteArrayInputStream(out.toByteArray())) {
    119. sftp.put(in, fileName+".ing");
    120. logger.info("the fourth step =========>{}", "transfer success");
    121. sftp.rename(baseDir + "/" + fileName+".ing", baseDir + "/" + fileName);
    122. logger.info("the fifth step =========>{}", "rename success");
    123. } catch (Exception e) {
    124. flag = false;
    125. throw new RuntimeException("sftp excetion" + e);
    126. } finally {
    127. disConnect(sftp);
    128. }
    129. return flag;
    130. }
    131. /**
    132. * 复制某路径下的文件到另外一个路径
    133. * 直接移动文件,用 ChannelSftp sftp.rename(String oldpath, String newpath)
    134. * @param config SftpConfig
    135. * @param sourceBaseDir 源文件路径
    136. * @param sourceFileName 源文件名称
    137. * @param destFilePath 目标文件路径
    138. * @param destFileName 目标文件名称
    139. * @return boolean
    140. */
    141. public static boolean copyFile(SftpConfig config, String sourceBaseDir, String sourceFileName, String destFilePath, String destFileName) {
    142. SftpChannel sftpChannel = new SftpChannel();
    143. ChannelSftp sftp;
    144. try {
    145. if (StringUtils.isNotBlank(config.getPrivateKeyPath())) {
    146. sftp = sftpChannel.connectByIdentity(config);
    147. } else {
    148. sftp = sftpChannel.connectByPwd(config);
    149. }
    150. if (sftp.isConnected()) {
    151. logger.info("connect server success");
    152. } else {
    153. logger.error("connect server fail");
    154. return false;
    155. }
    156. String dest;
    157. if (StringUtils.isBlank(destFileName)) {
    158. dest = destFilePath + sourceFileName;
    159. } else {
    160. dest = destFilePath + destFileName;
    161. }
    162. String src = sourceBaseDir + "/" + sourceFileName;
    163. logger.info("start downing,sftp server path:[" + src + "] dest server path:[" + dest + "]");
    164. //获取文件的大小
    165. SftpATTRS attr = sftp.stat(src);
    166. long fileSize = attr.getSize();
    167. logger.info("downing file size :" + fileSize);
    168. sftp.get(src, dest);
    169. logger.info("download success");
    170. return true;
    171. } catch (Exception e) {
    172. logger.error("download fail", e);
    173. return false;
    174. } finally {
    175. sftpChannel.closeChannel();
    176. }
    177. }
    178. /**
    179. *
    180. * @param config SftpConfig
    181. * @param baseDir sftp 路径
    182. * @param sourceFileName sftp 文件名称
    183. * @param savePath 本地路径
    184. * @param destFileName 本地文件名称
    185. * @return 返回文件路径
    186. * @throws SftpException
    187. * @throws JSchException
    188. * @throws IOException
    189. */
    190. public static String downToLocal(SftpConfig config, String baseDir, String sourceFileName, String savePath, String destFileName) throws SftpException, JSchException, IOException {
    191. SftpChannel sftpChannel = new SftpChannel();
    192. ChannelSftp sftp = null;
    193. String localPath = "";
    194. try {
    195. if (StringUtils.isNotBlank(config.getPrivateKeyPath())) {
    196. sftp = sftpChannel.connectByIdentity(config);
    197. } else {
    198. sftp = sftpChannel.connectByPwd(config);
    199. }
    200. if (sftp.isConnected()) {
    201. logger.info("connect server success");
    202. } else {
    203. logger.error("connect server fail");
    204. }
    205. String src = baseDir + "/" + sourceFileName;
    206. logger.info("start downing,sftp server path:[" + src + "]");
    207. //获取文件的大小
    208. SftpATTRS attr = sftp.stat(src);
    209. long fileSize = attr.getSize();
    210. logger.info("downing file size :" + fileSize);
    211. InputStream is = sftp.get(src);
    212. ByteArrayOutputStream out = new ByteArrayOutputStream();
    213. int len;
    214. byte[] bytes = new byte[1024];
    215. while ((len = is.read(bytes)) != -1) {
    216. out.write(bytes, 0, len);
    217. }
    218. File saveDir = new File(savePath);
    219. if(!saveDir.exists()){ // 没有就创建该文件
    220. saveDir.mkdir();
    221. }
    222. File file = new File(saveDir+File.separator+(System.currentTimeMillis()/10000)+destFileName);
    223. FileOutputStream fos = new FileOutputStream(file);
    224. fos.write(bytes);
    225. fos.close();
    226. is.close();
    227. return file.getPath();
    228. } finally {
    229. sftpChannel.closeChannel();
    230. }
    231. }
    232. /**
    233. * 判断文件夹是否存在
    234. * true 目录创建成功,false 目录创建失败
    235. * @param sftp ChannelSftp
    236. * @param filePath 文件夹路径
    237. * @return boolean
    238. */
    239. public static boolean isExist(ChannelSftp sftp, String filePath) {
    240. String paths[] = filePath.split("/");
    241. String dir = paths[0];
    242. for (int i = 0; i < paths.length - 1; i++) {
    243. dir = dir + "/" + paths[i + 1];
    244. try {
    245. sftp.cd(dir);
    246. } catch (SftpException sException) {
    247. if (ChannelSftp.SSH_FX_NO_SUCH_FILE == sException.id) {
    248. try {
    249. sftp.mkdir(dir);
    250. } catch (SftpException e) {
    251. e.printStackTrace();
    252. return false;
    253. }
    254. }
    255. }
    256. }
    257. return true;
    258. }
    259. /**
    260. * 获取文件数据
    261. * @param sftp ChannelSftp
    262. * @param ftpRootDir 文件路径及名称, 比如/home/ddzxsftp/ivr/33.txt
    263. * @return List
    264. */
    265. public static List<String> getList(ChannelSftp sftp, String ftpRootDir) {
    266. List<String> list = new ArrayList<>();
    267. try {
    268. InputStream is = sftp.get(ftpRootDir);
    269. String str;
    270. BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
    271. while ((str = br.readLine()) != null) {
    272. list.add(str);
    273. }
    274. br.close();
    275. } catch (Exception e) {
    276. logger.error("get file data excetion {}", e);
    277. }
    278. return list;
    279. }
    280. /**
    281. * 断掉连接
    282. */
    283. public void disConnect(ChannelSftp sftp) {
    284. try {
    285. sftp.disconnect();
    286. sftp.getSession().disconnect();
    287. } catch (Exception e) {
    288. logger.error("disConnect errorMessage",e);
    289. }
    290. }
    291. /**
    292. * 获取配置表里面配置sftp连接的内容
    293. * 把连接信息配置在数据库
    294. */
    295. public static SftpConfig getSftpConfigVal() {
    296. String configVal = "{\"ftpHost\":\"132.65.205.86\",\"ftpPort\":\"22\",\"ftpUserName\":\"yan\",\"ftpPassword\":\"KG@055\",\"ftpBaseDir\":\"/home/sftp\",\"path\":\"/home/sftp/ivr\",\"privateKeyPath\":\"\",\"passphrase\":\"\"}";
    297. JSONObject configObj = JSON.parseObject(configVal);
    298. String ftpHost = MapUtils.getString(configObj, "ftpHost");
    299. int ftpPort = MapUtils.getInteger(configObj, "ftpPort");
    300. String ftpUserName = MapUtils.getString(configObj, "ftpUserName");
    301. String ftpPassword = MapUtils.getString(configObj, "ftpPassword");
    302. String ftpBaseDir = MapUtils.getString(configObj, "ftpBaseDir");
    303. String path = MapUtils.getString(configObj, "path");
    304. String privateKeyPath = MapUtils.getString(configObj, "privateKeyPath");
    305. String passphrase = MapUtils.getString(configObj, "passphrase");
    306. SftpConfig config = new SftpConfig();
    307. config.setIp(ftpHost);
    308. config.setPort(ftpPort);
    309. config.setUsername(ftpUserName);
    310. config.setPwd(ftpPassword);
    311. config.setBaseDir(ftpBaseDir);
    312. config.setPath(path);
    313. config.setPrivateKeyPath(privateKeyPath);
    314. config.setPassphrase(passphrase);
    315. return config;
    316. }
    317. }

    总结:

            用cd(): 进入指定目录,然后用ls(): 得到指定目录下的文件列表,可以指定具体的文件类型。读取文件后,再用 rename(): 移动文件。了解ChannelSftp命令,要操作服务器上的文件就方便很多

  • 相关阅读:
    将本地jar包手动添加到Maven仓库依赖处理
    算法通过村第十三关-术数|黄金笔记|数论问题
    linux下生成rsa密钥的方法
    从油猴脚本管理器的角度审视Chrome扩展
    我的vs把opencv配置进去了,通过几个测试代码显示可以,但是运行的时候报错经过验证图片路径和地址附加依赖项没有配置错))
    【OCRA学习】在linux系统安装ORCA,并与xtb联用配置
    Discourse 的用户快速找到管理员账号
    Aspose.PDF for Java Crack by Xacker
    AI强势入场,成就史上最快足球
    JSP(Java Server Pages)
  • 原文地址:https://blog.csdn.net/qq_35461948/article/details/126579693