用Java下载整个FTP目录(Apache Net Commons)

我试图递归遍历登录到FTP服务器后到达的整个根目录。

我能够连接,所有我真正想做的就是通过整个结构进行递归并下载每个文件和文件夹,并使其与FTP上的结构相同。 到目前为止我所拥有的是一个有效的下载方法,它进入服务器并获取我的整个文件结构,这很棒,除非它在第一次尝试时失败,然后第二次工作。 我得到的错误如下:

java.io.FileNotFoundException:output-directory \ test \ testFile.png(系统找不到指定的路径)

我设法上传了我在本地的目录的上传function,但是经过多次尝试我无法完全下载工作,我真的需要一些帮助。

public static void download(String filename, String base) { File basedir = new File(base); basedir.mkdirs(); try { FTPFile[] ftpFiles = ftpClient.listFiles(); for (FTPFile file : ftpFiles) { if (!file.getName().equals(".") && !file.getName().equals("..")) { // If Dealing with a directory, change to it and call the function again if (file.isDirectory()) { // Change working Directory to this directory. ftpClient.changeWorkingDirectory(file.getName()); // Recursive call to this method. download(ftpClient.printWorkingDirectory(), base); // Create the directory locally - in the right place File newDir = new File (base + "/" + ftpClient.printWorkingDirectory()); newDir.mkdirs(); // Come back out to the parent level. ftpClient.changeToParentDirectory(); } else { ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); String remoteFile1 = ftpClient.printWorkingDirectory() + "/" + file.getName(); File downloadFile1 = new File(base + "/" + ftpClient.printWorkingDirectory() + "/" + file.getName()); OutputStream outputStream1 = new BufferedOutputStream(new FileOutputStream(downloadFile1)); boolean success = ftpClient.retrieveFile(remoteFile1, outputStream1); outputStream1.close(); } } } } catch(IOException ex) { System.out.println(ex); } } 

你的问题(好吧,我们摆脱了.并且你已经超过了二进制问题之后的当前问题)是你在调用newDir.mkdirs()之前正在进行递归步骤。

所以假设你有一棵树

 . .. someDir . .. someFile.txt someOtherDir . .. someOtherFile.png 

你要做的是跳过点文件,看看someDir是一个目录,然后立即进入它,跳过它的点文件,并看到someFile.txt ,并处理它。 你还没有在本地创建someDir ,所以你得到一个例外。

您的exception处理程序不会停止执行,因此控制将返回到递归的上一级。 此时它会创建目录。

因此,下次运行程序时,已经从上一次运行创建了本地someDir目录,并且您没有看到任何问题。

基本上,您应该将代码更改为:

  if (file.isDirectory()) { // Change working Directory to this directory. ftpClient.changeWorkingDirectory(file.getName()); // Create the directory locally - in the right place File newDir = new File (base + "/" + ftpClient.printWorkingDirectory()); newDir.mkdirs(); // Recursive call to this method. download(ftpClient.printWorkingDirectory(), base); // Come back out to the parent level. ftpClient.changeToParentDirectory(); } 

一个完整的独立代码,用于从FTP文件夹递归下载所有文件:

 private static void downloadFolder( FTPClient ftpClient, String remotePath, String localPath) throws IOException { System.out.println("Downloading folder " + remotePath + " to " + localPath); FTPFile[] remoteFiles = ftpClient.listFiles(remotePath); for (FTPFile remoteFile : remoteFiles) { if (!remoteFile.getName().equals(".") && !remoteFile.getName().equals("..")) { String remoteFilePath = remotePath + "/" + remoteFile.getName(); String localFilePath = localPath + "/" + remoteFile.getName(); if (remoteFile.isDirectory()) { new File(localFilePath).mkdirs(); downloadFolder(ftpClient, remoteFilePath, localFilePath); } else { System.out.println("Downloading file " + remoteFilePath + " to " + localFilePath); OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(localFilePath)); if (!ftpClient.retrieveFile(remoteFilePath, outputStream)) { System.out.println("Failed to download file " + remoteFilePath); } outputStream.close(); } } } }