简体   繁体   English

如何从 SFTP 服务器获取文件列表?

[英]How to get list of files from an SFTP server?

I have a problem and hoping to get a solution.我有一个问题,希望得到解决方案。 I also have written some code but it needs some modification.我也写了一些代码,但它需要一些修改。

Problem: I have a SFTP server (for privacy purposes I will give dummy credentials) that I need to connect to.问题:我有一个需要连接的 SFTP 服务器(出于隐私目的,我将提供虚拟凭据)。

Server name: server-name服务器名称:服务器名称
port: 22端口:22
username: username用户名:用户名
password: password密码:密码

When I connect to the server, it automatically drops me in the /FGV directory.当我连接到服务器时,它会自动将我放到/FGV目录中。 inside this directory are couple other folders.在这个目录中有几个其他文件夹。 I need to grab a LIST of xml messages from the /FGV/US/BS/ directory and place them in a LIST (files in the form of File).我需要从/FGV/US/BS/目录中获取一个 xml 消息列表并将它们放在一个列表中(文件形式的文件)。 In the list, I need to have the directory of the file, file name and the file body.在列表中,我需要有文件的目录、文件名和文件体。 I was thinking of creating an object and putting this information in there and creating a List of that object.我正在考虑创建一个对象并将这些信息放在那里并创建该对象的列表。

My current code creates a connection and downloads only ONE xml file.我当前的代码创建一个连接并只下载一个 xml 文件。 If there are two xml files, then the file in my local machine has nothing as content.如果有两个xml文件,那么我本地机器中的文件就没有内容了。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

public class SFTPinJava {

    public SFTPinJava() {
    }

    public static void main(String[] args) {
        String SFTPHOST = "server-name";
        int SFTPPORT = 22;
        String SFTPUSER = "username";
        String SFTPPASS = "password";
        String SFTPWORKINGDIR = "/FGV";

        Session session = null;
        Channel channel = null;
        ChannelSftp channelSftp = null;

        try {
            JSch jsch = new JSch();
            session = jsch.getSession(SFTPUSER, SFTPHOST, SFTPPORT);
            session.setPassword(SFTPPASS);
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
            channel = session.openChannel("sftp");
            channel.connect();
            channelSftp = (ChannelSftp) channel;
            channelSftp.cd(SFTPWORKINGDIR);
            byte[] buffer = new byte[1024];
            BufferedInputStream bis = new BufferedInputStream(
                channelSftp.get("/FGV/US/BS/FGVCustomsEntryLoaderService.xml"));
            File newFile = new File(
                "C:\\workspace\\Crap\\src\\org\\raghav\\stuff\\XML_FROM_SERVER.xml");
            OutputStream os = new FileOutputStream(newFile);
            BufferedOutputStream bos = new BufferedOutputStream(os);
            int readCount;
            //System.out.println("Getting: " + theLine);
            while ((readCount = bis.read(buffer)) > 0) {
                //System.out.println("Writing: ");
                bos.write(buffer, 0, readCount);
            }
            
            while(session != null){
                System.out.println("Killing the session");
                session.disconnect();
                bis.close();
                bos.close();
                System.exit(0);
            }
            
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

I need to change this code so that it would grab multiple files and puts them in a list of objects.我需要更改此代码,以便它可以抓取多个文件并将它们放入对象列表中。 that object should have the directory of the file, the file name and the body of the file.该对象应具有文件目录、文件名和文件正文。

you can list all files in the given directory using您可以使用列出给定目录中的所有文件

Vector<ChannelSftp.LsEntry> list = channelSftp.ls("*.csv");
for(ChannelSftp.LsEntry entry : list) {
     System.out.println(entry.getFilename()); 
}

add this code after在之后添加此代码

channelSftp.cd(SFTPWORKINGDIR);

now you'll get list of file objects.现在您将获得文件对象列表。 file object is entry.if you want to download all files .文件对象是条目。如果要下载所有文件。 add this code inside to for loop.将此代码添加到 for 循环中。

byte[] buffer = new byte[1024];
BufferedInputStream bis = new BufferedInputStream(channelSftp.get(entry.getFilename()));
File newFile = new File("C:/Users/Desktop/sftpStuff/"+entry.getFilename());
OutputStream os = new FileOutputStream(newFile);
BufferedOutputStream bos = new BufferedOutputStream(os);
int readCount;
//System.out.println("Getting: " + theLine);
while( (readCount = bis.read(buffer)) > 0) {
  System.out.println("Writing: "+entry.getFilename() );
  bos.write(buffer, 0, readCount);
}
bis.close();
bos.close();

This is a way to list files of destination directory.这是一种列出目标目录文件的方法。

Vector filelist = channelSftp.ls(SFTPWORKINGDIR);
for(int i=0; i<filelist.size();i++){
     System.out.println(filelist.get(i).toString());
     // Grap and get the file by WORKING_DIR/filelist.get(i).toString();
     // Save it to your local directory with its original name. 

}

Second, while in for loop you can download all files if they are requested xml files those you need.其次,在 for 循环中,您可以下载所有文件,如果它们是您需要的 xml 文件。

ChannelSftp has a method to obtain a list of files from a path. ChannelSftp 有一种方法可以从路径中获取文件列表。 I'm assuming the files you want to download are all in the in the same directory and that you would do:我假设您要下载的文件都在同一目录中,并且您会这样做:

channelSftp.cd("/FGV/US/BS/");
Vector ls = channelSftp.ls("*")

http://epaul.github.io/jsch-documentation/simple.javadoc/com/jcraft/jsch/ChannelSftp.html#ls(java.lang.String) http://epaul.github.io/jsch-documentation/simple.javadoc/com/jcraft/jsch/ChannelSftp.html#ls(java.lang.String)

Once you have that list (a Vector is returned), set up a for loop or iterator to use each ChannelSftp.LsEntry in the Vector, using the getFilename method to obtain the filename.获得该列表(返回 Vector)后,设置 for 循环或迭代器以使用 Vector 中的每个 ChannelSftp.LsEntry,使用 getFilename 方法获取文件名。 You can check to make sure it has an .xml extension.您可以检查以确保它具有 .xml 扩展名。 Everything from the byte[] buffer line on in your code goes inside the loop.代码中byte[] buffer行中的所有内容都在循环内。 You'll need to add successive reads to your buffer to a StringBuffer if you want to preserve the contents of the file.如果要保留文件的内容,则需要将连续读取的缓冲区添加到 StringBuffer。

As for storing the filename, contents of each, and directory, you could use a simple wrapper.至于存储文件名、每个文件的内容和目录,您可以使用一个简单的包装器。 Example:例子:

public class SFTPFileList {
    public String directory;
    public ArrayList<String> filenames;
    public ArrayList<StringBuffer> fileContents;  

    /**
     *Simple method to add a filename and its contents.
     *filenames and fileContents will have the same index
     *for filename<->content. 
     **/
    public void addFile(String filename, StringBuffer content) {
        filenames.add(filename);
        fileContents.add(content);
    }
}

You can add methods, constructor, etc. to properly get, set.您可以添加方法、构造函数等以正确获取、设置。 Or access directly.或者直接访问。 For the latter, outside your loop:对于后者,在你的循环之外:

SFTPFileList sftpFileList = new SFTPFileList();
sftpFileList.directory = "/FGV/US/BS/";
ArrayList<String> fileNames = new ArrayList<>();
ArrayList<String,StringBuffer> contents = new ArrayList<>();
sftpFileList.filenames = filenames;
sftpFileList.contents = contents;

Inside your loop:在你的循环中:

ChannelSftp.LsEntry entry = iter.next();  //or from a for loop
String fileName = entry.getFileName();
StringBuffer fileContent = new StringBuffer(); //this where you will add the results of each read -> buffer 
...
read content
...
sftpFileList.addFile(fileName,fileContent);

Then outside of the loop you'll have access to all the filenames and their content via another method or methods that you can write.然后在循环之外,您将可以通过另一种或多种您可以编写的方法访问所有文件名及其内容。 Or directly access those members as necessary.或者根据需要直接访问这些成员。

This code is working well.这段代码运行良好。

        @SuppressWarnings("null")
        Vector<ChannelSftp.LsEntry> filesList = channelSftp.ls("*.txt");
        logger.info("filesList size:" + filesList.size()); 
        if(filesList != null) {
            for(ChannelSftp.LsEntry entry : filesList) {
                InputStream stream = channelSftp.get(entry.getFilename());
                br = new BufferedReader(new InputStreamReader(stream));
                if(br != null) {
                    while ((line = br.readLine()) != null) {
                    }
                }
           }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM