Я хочу перенести папку и подпапку с помощью JSch ChannelSftp
. Я могу успешно передавать файлы с помощью команды channelsftp.put(src, dest)
, но это не работает для папок (по крайней мере, я не мог заставить это работать). Так может кто-нибудь объяснить, как я могу передавать папки и подпапки с помощью ChannelSftp
?
Перенести папку и подпапки с помощью ChannelSftp в JSch?
Ответы (3)
Для работы с многоуровневыми структурами папок в jsch необходимо:
- введите их;
- перечислить их содержимое;
- сделать что-то с каждым найденным предметом;
- повторите 1, 2 и 3, если подпапка найдена.
СКАЧАТЬ метод dirs внутри вашего класса JSCH:
public void downloadDir(String sourcePath, String destPath) throws SftpException { // With subfolders and all files.
// Create local folders if absent.
try {
new File(destPath).mkdirs();
} catch (Exception e) {
System.out.println("Error at : " + destPath);
}
sftpChannel.lcd(destPath);
// Copy remote folders one by one.
lsFolderCopy(sourcePath, destPath); // Separated because loops itself inside for subfolders.
}
private void lsFolderCopy(String sourcePath, String destPath) throws SftpException { // List source (remote, sftp) directory and create a local copy of it - method for every single directory.
Vector<ChannelSftp.LsEntry> list = sftpChannel.ls(sourcePath); // List source directory structure.
for (ChannelSftp.LsEntry oListItem : list) { // Iterate objects in the list to get file/folder names.
if (!oListItem.getAttrs().isDir()) { // If it is a file (not a directory).
if (!(new File(destPath + "/" + oListItem.getFilename())).exists() || (oListItem.getAttrs().getMTime() > Long.valueOf(new File(destPath + "/" + oListItem.getFilename()).lastModified() / (long) 1000).intValue())) { // Download only if changed later.
new File(destPath + "/" + oListItem.getFilename());
sftpChannel.get(sourcePath + "/" + oListItem.getFilename(), destPath + "/" + oListItem.getFilename()); // Grab file from source ([source filename], [destination filename]).
}
} else if (!(".".equals(oListItem.getFilename()) || "..".equals(oListItem.getFilename()))) {
new File(destPath + "/" + oListItem.getFilename()).mkdirs(); // Empty folder copy.
lsFolderCopy(sourcePath + "/" + oListItem.getFilename(), destPath + "/" + oListItem.getFilename()); // Enter found folder on server to read its contents and create locally.
}
}
}
УДАЛИТЕ метод dirs внутри вашего класса JAO:
try {
sftpChannel.cd(dir);
Vector<ChannelSftp.LsEntry> list = sftpChannel.ls(dir); // List source directory structure.
for (ChannelSftp.LsEntry oListItem : list) { // Iterate objects in the list to get file/folder names.
if (!oListItem.getAttrs().isDir()) { // If it is a file (not a directory).
sftpChannel.rm(dir + "/" + oListItem.getFilename()); // Remove file.
} else if (!(".".equals(oListItem.getFilename()) || "..".equals(oListItem.getFilename()))) { // If it is a subdir.
try {
sftpChannel.rmdir(dir + "/" + oListItem.getFilename()); // Try removing subdir.
} catch (Exception e) { // If subdir is not empty and error occurs.
lsFolderRemove(dir + "/" + oListItem.getFilename()); // Do lsFolderRemove on this subdir to enter it and clear its contents.
}
}
}
sftpChannel.rmdir(dir); // Finally remove the required dir.
} catch (SftpException sftpException) {
System.out.println("Removing " + dir + " failed. It may be already deleted.");
}
ВЫЗВАТЬ эти методы извне, например:
MyJSCHClass sftp = new MyJSCHClass();
sftp.removeDir("/mypublic/myfolders");
sftp.disconnect(); // Disconnecting is obligatory - otherwise changes on server can be discarded (e.g. loaded folder disappears).
person
Zon
schedule
21.10.2013
Приведенный выше код (от zon) работает для загрузки, насколько я понимаю. Мне нужно загрузить на удаленный сервер. Я написал код ниже, чтобы добиться того же. Попробуйте и прокомментируйте, если возникнут какие-либо проблемы (он игнорирует файлы, начинающиеся с «.»)
private static void lsFolderCopy(String sourcePath, String destPath,
ChannelSftp sftpChannel) throws SftpException, FileNotFoundException {
File localFile = new File(sourcePath);
if(localFile.isFile())
{
//copy if it is a file
sftpChannel.cd(destPath);
if(!localFile.getName().startsWith("."))
sftpChannel.put(new FileInputStream(localFile), localFile.getName(),ChannelSftp.OVERWRITE);
}
else{
System.out.println("inside else "+localFile.getName());
File[] files = localFile.listFiles();
if(files!=null && files.length > 0 && !localFile.getName().startsWith("."))
{
sftpChannel.cd(destPath);
SftpATTRS attrs = null;
//check if the directory is already existing
try {
attrs = sftpChannel.stat(destPath+"/"+localFile.getName());
} catch (Exception e) {
System.out.println(destPath+"/"+localFile.getName()+" not found");
}
//else create a directory
if (attrs != null) {
System.out.println("Directory exists IsDir="+attrs.isDir());
} else {
System.out.println("Creating dir "+localFile.getName());
sftpChannel.mkdir(localFile.getName());
}
//System.out.println("length " + files.length);
for(int i =0;i<files.length;i++)
{
lsFolderCopy(files[i].getAbsolutePath(),destPath+"/"+localFile.getName(),sftpChannel);
}
}
}
}
person
Kalyan Chakravarthi
schedule
28.08.2015
JCH предназначен для удаленного подключения. Для работы с локальной файловой системой лучше использовать класс java.io.File. Но вы можете попробовать подключить свой локальный хост, как если бы он был удаленным.
- person Zon; 29.09.2015
Zon.. этот код, который я разместил, предназначен для загрузки в удаленную систему... (Этот код использовался для загрузки файла уха из коробки разработчика в коробку сервера - как бы автоматически с использованием jenkins..)
- person Kalyan Chakravarthi; 05.11.2015
Это отличный код, и он отлично работает. но что, если я хочу скопировать файлы, начинающиеся с точки (.). После комментирования этой строки все еще не копируется то же самое?
- person Aditya; 30.04.2017
Да, следует... попробуйте прокомментировать эту строку: if(!localFile.getName().startsWith(.))
- person Kalyan Chakravarthi; 01.05.2017
Из: http://the-project.net16.net/Projekte/projekte/Projekte/Programmieren/sftp-synchronisierung.html
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Vector;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.SftpException;
public class FileMaster {
public boolean FileAction;
public File local;
public String serverDir;
public ChannelSftp channel;
public FileMaster(boolean copyOrDelete, File local, String to, ChannelSftp channel){
this.FileAction = copyOrDelete;
this.local = local;
this.serverDir = to;
this.channel = channel;
}
/*
* If FileAction = true, the File local is copied to the serverDir, else the file is deleted.
*/
public void runMaster() throws FileNotFoundException, SftpException{
if(FileAction){
copy(local, serverDir, channel);
} else {
delete(serverDir, channel);
}
}
/*
* Copies recursive
*/
public static void copy(File localFile, String destPath, ChannelSftp clientChannel) throws SftpException, FileNotFoundException{
if(localFile.isDirectory()){
clientChannel.mkdir(localFile.getName());
GUI.addToConsole("Created Folder: " + localFile.getName() + " in " + destPath);
destPath = destPath + "/" + localFile.getName();
clientChannel.cd(destPath);
for(File file: localFile.listFiles()){
copy(file, destPath, clientChannel);
}
clientChannel.cd(destPath.substring(0, destPath.lastIndexOf('/')));
} else {
GUI.addToConsole("Copying File: " + localFile.getName() + " to " + destPath);
clientChannel.put(new FileInputStream(localFile), localFile.getName(),ChannelSftp.OVERWRITE);
}
}
/*
* File/Folder is deleted, but not recursive
*/
public void delete(String filename, ChannelSftp sFTPchannel) throws SftpException{
if(sFTPchannel.stat(filename).isDir()){
@SuppressWarnings("unchecked")
Vector<LsEntry> fileList = sFTPchannel.ls(filename);
sFTPchannel.cd(filename);
int size = fileList.size();
for(int i = 0; i < size; i++){
if(!fileList.get(i).getFilename().startsWith(".")){
delete(fileList.get(i).getFilename(), sFTPchannel);
}
}
sFTPchannel.cd("..");
sFTPchannel.rmdir(filename);
} else {
sFTPchannel.rm(filename.toString());
}
GUI.addToConsole("Deleted: " + filename + " in " + sFTPchannel.pwd());
}
}
person
Lukas Käppeli
schedule
03.02.2017