Java獲取Linux上指定文件夾下所有第一級子文件夾


說明:需要只獲得第一級文件夾目錄 

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;
    }

}

 

 

 

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

使用ch.ethz.ssh2中sess.execCommand方法導致線程卡死的原因分析

技術標簽: ssh2  sess.execCommand  線程卡死

 

背景

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

分析

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

線程現在一直在c.wait這里,等待服務器返回信息將他喚醒。
問題是服務器不知道啥情況,就是不返回,所以線程就一直卡在這里了

解決方案

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

/*
*列出目錄下的文件信息
*/
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;
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM