私は問題を抱えており、解決策を得たいと思っています。私もいくつかのコードを書きましたが、いくつかの変更が必要です。
問題:接続する必要のあるSFTPサーバー(プライバシー保護のためにダミーの資格情報を提供します)があります。
サーバー名:サーバー名ポート:22ユーザー名:ユーザー名パスワード:パスワード
サーバーに接続すると、自動的に「/ FGV」ディレクトリにドロップされます。このディレクトリ内には、他のいくつかのフォルダがあります。 「/ FGV/US/BS /」ディレクトリからxmlメッセージのリストを取得し、それらをLIST(ファイル形式のファイル)に配置する必要があります。リストには、ファイルのディレクトリ、ファイル名、ファイル本体が必要です。オブジェクトを作成してそこにこの情報を入れ、そのオブジェクトのリストを作成することを考えていました。
私の現在のコードは接続を作成し、1つのxmlファイルのみをダウンロードします。 2つの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();
}
}
}
このコードを変更して、複数のファイルを取得し、それらをオブジェクトのリストに配置する必要があります。そのオブジェクトには、ファイルのディレクトリ、ファイル名、およびファイルの本文が含まれている必要があります。
を使用して、指定されたディレクトリ内のすべてのファイルを一覧表示できます。
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();
ChannelSftpには、パスからファイルのリストを取得するメソッドがあります。ダウンロードしたいファイルはすべて同じディレクトリにあり、次のようにすることを前提としています。
channelSftp.cd("/FGV/US/BS/");
Vector ls = channelSftp.ls("*")
そのリストを取得したら(ベクターが返されます)、getFilenameメソッドを使用してファイル名を取得し、ベクター内の各ChannelSftp.LsEntryを使用するようにforループまたはイテレーターを設定します。拡張子が.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);
次に、ループの外側で、作成可能な別の1つまたは複数のメソッドを介してすべてのファイル名とそのコンテンツにアクセスできます。または、必要に応じてそれらのメンバーに直接アクセスします。
これは、宛先ディレクトリのファイルを一覧表示する方法です。
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ファイルが要求された場合にすべてのファイルをダウンロードできます。
このコードはうまく機能しています。
@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) {
}
}
}
}