我有一个问题,希望得到一个解决方案。我也编写了一些代码,但需要进行一些修改。
问题: 我有一个SFTP服务器(出于隐私目的,我将提供虚拟凭据),我需要连接到。
服务器名称:server-name 港口:22 用户名:用户名 密码:密码
当我连接到服务器时,它会自动将我放入“/ FGV”目录中。在这个目录里面是其他几个文件夹。我需要从“/ FGV / US / BS /”目录中获取xml消息列表,并将它们放在LIST(文件形式的文件)中。在列表中,我需要有文件目录,文件名和文件正文。我正在考虑创建一个对象并将此信息放在那里并创建该对象的List。
我当前的代码创建一个连接并仅下载一个xml文件。如果有两个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();
}
}
}
我需要更改此代码,以便它可以获取多个文件并将它们放入对象列表中。该对象应具有文件目录,文件名和文件正文。
答案 0 :(得分:14)
您可以使用
列出给定目录中的所有文件Vector<ChannelSftp.LsEntry> list = channelSftp.ls("*.csv");
for(ChannelSftp.LsEntry entry : list) {
System.out.println(entry.getFilename());
}
在
之后添加此代码channelSftp.cd(SFTPWORKINGDIR);
现在您将获得文件对象列表。如果要下载所有文件,则文件对象为entry。将此代码添加到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();
答案 1 :(得分:2)
这是一种列出目标目录文件的方法。
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.
}
其次,在for循环中,如果需要xml文件,则可以下载所有文件。
答案 2 :(得分:2)
ChannelSftp有一种方法可以从路径中获取文件列表。我假设您要下载的文件都在同一目录中,您可以这样做:
channelSftp.cd("/FGV/US/BS/");
Vector ls = channelSftp.ls("*")
获得该列表(返回Vector)后,设置for循环或迭代器以使用Vector中的每个ChannelSftp.LsEntry,使用getFilename方法获取文件名。您可以检查以确保它具有.xml扩展名。代码中byte[] buffer
行的所有内容都在循环内部。如果要保留文件的内容,则需要向缓冲区添加连续读取到StringBuffer。
至于存储文件名,每个文件的内容和目录,你可以使用一个简单的包装器。例如:
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);
}
}
您可以添加方法,构造函数等来正确获取,设置。或直接访问。对于后者,在你的循环之外:
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;
在你的循环中:
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);
然后,在循环之外,您可以通过另一种可以编写的方法访问所有文件名及其内容。或者根据需要直接访问这些成员。
答案 3 :(得分:0)
此代码运行良好。
@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) {
}
}
}
}