2017-04-05 9 views
3

SFTPフォルダにファイル名の再帰的リストを取得する必要があります。SFTPの最初のN個のファイルをJSchで一覧表示する

@SuppressWarnings("unchecked") 
public List<LsEntry> listFiles(String pathFrom) throws SftpException { 
    if (c == null || session == null || !session.isConnected() || !c.isConnected()) { 
     throw new SftpException(ErrorCode.LIST_FILES.ordinal(), "Connection to server is closed. Open it first."); 
    } 
    String filePath = pathFrom + "/"; 
    return c.ls(filePath); 
} 

すべてが無よりも5Kのファイルでうまく動作しますが、我々はより多くのファイルを持っている場合、それは多くを取ります

private void getFilesRecursive(List<LsEntry> fileList, List<FileDto> response, String dirParentName, 
     SftpManagerWithPool manager) throws SftpException { 
    for (LsEntry file : fileList) { 
     if (!file.getAttrs().isDir()) { 
      response.add(new FileDto(file.getFilename(), StorageType.FOLDER.getName(), 
        new Attributes(file.getAttrs().getATime(), file.getAttrs().getMTime(), 
          file.getAttrs().getAtimeString(), file.getAttrs().getMtimeString(), 
          file.getAttrs().getPermissionsString(), getPathWitoutRootDirectoryt(dirParentName), 
          file.getAttrs().getSize(), file.getAttrs().isDir()))); 
     } else if (file.getAttrs().isDir() && !".".equals(file.getFilename())) { 
      List<LsEntry> files = manager.listFiles(context.getBasePath().concat("/") 
        .concat(dirParentName.concat("/").concat(file.getFilename()))); 
      getFilesRecursive(files, response, dirParentName.concat("/").concat(file.getFilename()), manager); 
     } 
    } 
} 

public List<FileDto> getFiles() throws ServiceException { 
    Session session = null; 
    SftpManagerWithPool manager = null; 
    try { 
     session = getSession(); 
     manager = new SftpManagerWithPool(session); 
     manager.connect(); 
     List<FileDto> response = new ArrayList<>(); 
     List<LsEntry> files = manager 
       .listFiles(context.getBasePath().concat("/").concat(context.getPathToProcess())); 
     getFilesRecursive(files, response, context.getPathToProcess(), manager); 
     return response; 
    } catch (Exception e) { 
     throw new ServiceException(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage(), 
       e.getLocalizedMessage()); 
    } finally { 
     if (manager != null) { 
      manager.disconnect(); 
      try { 
       returnSession(session); 
      } catch (Exception e) { 
       throw new ServiceException(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage(), 
         e.getLocalizedMessage()); 
      } 
     } 
    } 
} 

次はSftpManagerWithPoolのメソッドです:今、私は、次のコードを使用していますタイムアウトが発生します。

私の質問は、c.ls(filePath);メソッドを使用して、フォルダ内の最初のN個のファイルのみを一覧表示するにはどうすればよいですか?私は、Linuxのシェルコマンドに似たものを探していますls -U | head -4

---- EDIT -----

私は次のように私の方法listFilesを変更しますが、私はまだ良いパフォーマンスを得ることはありません:

public List<LsEntry> listFiles(String pathFrom, int top) throws SftpException { 
     if (c == null || session == null || !session.isConnected() || !c.isConnected()) { 
      throw new SftpException(ErrorCode.LIST_FILES.ordinal(), "Connection to server is closed. Open it first."); 
     } 
     String filePath = pathFrom + "/"; 
     List<LsEntry> response = new ArrayList<>(); 
     c.ls(filePath, new LsEntrySelector() { 

      @Override 
      public int select(LsEntry record) { 
       if (response.size() <= top) { 
        response.add(record); 
        return LsEntrySelector.CONTINUE; 
       } else { 
        return LsEntrySelector.BREAK; 
       } 
      } 
     }); 
     return response; 
    } 

はどうもありがとう:)

答えて

2

使用このoverload of ChannelSftp.ls method that takes LsEntrySelector interfaceを:

public void ls(String path, LsEntrySelector selector) 

LsEntrySelector.selectを実装して、ファイルエントリを収集します。十分なものがあれば、BREAKを返します。

+0

しかし、それは無効を返しますどのようにファイルのリストを取得できますか? –

+0

'LsEntrySelector.select'の名前をいくつかのコンテナ(例えば' Vector')に集めます。 –

+0

私の編集内容を確認してください、あなたの言ったことはやっているようですが、それは動作しているように見えますが、まだファイルをリストしてもパフォーマンスは良くなりません。ファイルを一覧表示するのに3分かかります –

関連する問題