Java獲取Linux上指定文件夾下全部第一級子文件夾

說明:須要只得到第一級文件夾目錄 java

package com.sunsheen.jfids.studio.monitor.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.Assert;

import ch.ethz.ssh2.ChannelCondition;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.StreamGobbler;


/**
 * 遍歷出遠程服務器上指定目錄下的全部文件夾
 * 
 * @author WangSong
 *
 */
public class GetAllSubfolders {

    private GetAllSubfolders(){}

    /**
     * 獲得服務器上指定文件夾下全部子文件夾(第一級子文件夾)
     * @return
     */
    public static List<Object> getSubfolderName(String romoteAddr,String username,
            String password,String targetFolder) {
        
        List<Object> folderNameList = new ArrayList<Object>();
        try {
              Connection connection = new Connection(romoteAddr);// 建立一個鏈接實例
              connection.connect();// Now connect
              boolean isAuthenticated = connection.authenticateWithPassword(username, password);//認證
              Assert.isTrue(isAuthenticated, "用戶名或密碼錯誤!");
              ch.ethz.ssh2.Session sess = connection.openSession();// 創建一個會話
              sess.requestPTY("bash");
              sess.startShell();
              InputStream stdout = new StreamGobbler(sess.getStdout());
              InputStream stderr = new StreamGobbler(sess.getStderr());
              BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(stdout));
              BufferedReader stderrReader = new BufferedReader(new InputStreamReader(stderr));
              //向服務器上輸入命令
              PrintWriter out = new PrintWriter(sess.getStdin());
              out.println("cd " + targetFolder);//進入日誌文件存放的目錄
              out.println("ls -ld */");
              out.println("exit");
              out.close();
              sess.waitForCondition(ChannelCondition.CLOSED|ChannelCondition.EOF | ChannelCondition.EXIT_STATUS,30000);
              
              //本機查看遠程操做的指令及狀態
              System.out.println("輸入指令後對應的顯示信息:");      
              while (true) {
                  String line = stdoutReader.readLine();
                  if (line == null)
                      break;
                  System.out.println(line);
                  //取出文件夾那條記錄
                  if(line.contains("drwxr-xr-x")){
                      //取出正確的文件夾名
                      StringBuffer sb = 
                              new StringBuffer(line.substring(line.lastIndexOf(" "),line.lastIndexOf("/")));
                      line = sb.toString().replace(" ", "");
                      folderNameList.add(line); 
                  }
              }
              System.out.println("ExitCode: " + sess.getExitStatus());
              
              //關閉鏈接
              sess.close();
              connection.close();
              stderrReader.close();
              stdoutReader.close();
          } catch (IOException e) {
              e.printStackTrace(System.err);
              System.exit(2);
          }
        return folderNameList;
    }

}

 

 

 

 上面代碼可能會出現線程阻塞(客戶端等待服務器應答信息),參考下面方式解決bash

使用ch.ethz.ssh2中sess.execCommand方法致使線程卡死的緣由分析

技術標籤: ssh2  sess.execCommand  線程卡死服務器

 

背景

前幾天有同事反饋,說生產上的定時任務好像卡住了,沒有執行。
上服務器,查看應用日誌,定時任務確實沒有執行。markdown

分析

這種狀況,第一時間先把線程dump文件導出來
分析dump文件,發現線程一直在執行sess.execCommand方法eclipse

線程如今一直在c.wait這裏,等待服務器返回信息將他喚醒。
問題是服務器不知道啥狀況,就是不返回,因此線程就一直卡在這裏了ssh

解決方案

通常來講能夠經過設置超時時間來處理這些問題。可是這個方法根本沒有超時時間設置的參數。
好在找到了waitForCondition這個方法,能夠設置一些條件來達到超時時間設置的效果.atom

/*
*列出目錄下的文件信息
*/
public static String[] getRemoteDirFileNames(Connection conn, String remoteDir){
        Session sess=null;
        try {
            sess = conn.openSession();
            sess.execCommand("ls -lt "+remoteDir);
            InputStream stdout = new StreamGobbler(sess.getStdout());
            InputStream stderr = new StreamGobbler(sess.getStderr());

            byte[] buffer = new byte[100];
            String result = "";
            while (true) {
                if ((stdout.available() == 0)) {
                    int conditions = sess.waitForCondition(ChannelCondition.STDOUT_DATA |
                            ChannelCondition.STDERR_DATA | ChannelCondition.EOF, 1000*5);
                    if ((conditions & ChannelCondition.TIMEOUT) != 0) {
                        break;//超時後退出循環,要保證超時時間內,腳本能夠運行完成
                    }
                    if ((conditions & ChannelCondition.EOF) != 0) {
                        if ((conditions & (ChannelCondition.STDOUT_DATA |
                                ChannelCondition.STDERR_DATA)) == 0) {
                            break;
                        }
                    }
                }

                if(stdout!=null){
                    String fileNames= ConvertUtil.parse_String(stdout);
                    if(fileNames!=null){
                        return fileNames.split("\n");
                    }
                }

                while (stderr.available() > 0) {
                    int len = stderr.read(buffer);
                    if (len > 0){
                        result += new String(buffer, 0, len);
                    }
                }
            }

        } catch (Exception e) {
            log.info("獲取指定目錄下文件列表失敗:"+e.getMessage());
        }finally {
            sess.close();
        }
        return null;
    }
相關文章
相關標籤/搜索