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

时间:2014-11-25 21:53:10

标签: java ftp apache-commons-net

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

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

  

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

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

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);
    }
}

2 个答案:

答案 0 :(得分:1)

你的问题(好吧,我们摆脱了...后你遇到二元问题时的当前问题)是你在调用{{1}之前正在进行递归步骤}。

假设你有一棵树

newDir.mkdirs()

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

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

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

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

someDir

答案 1 :(得分:0)

从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();
            }
        }
    }
}