简体   繁体   English

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

[英]Download entire FTP directory in Java (Apache Net Commons)

I am trying to recursively iterate through the entire root directory that I arrive at after login to the FTP server. 我试图递归遍历登录FTP服务器后到达的整个根目录。

I am able to connect, all I really want to do from there is recurse through the entire structure and and download each file and folder and have it in the same structure as it is on the FTP. 我能够连接,我真正想要做的就是遍历整个结构,然后下载每个文件和文件夹,并使其具有与FTP相同的结构。 What I have so far is a working download method, it goes to the server and gets my entire structure of files, which is brilliant, except it fails on the first attempt, then works the second time around. 到目前为止,我所拥有的是一种有效的下载方法,它可以进入服务器并获取我的整个文件结构,这很不错,只是它在第一次尝试时失败,然后在第二次尝试时失败了。 The error I get is as follows: 我得到的错误如下:

java.io.FileNotFoundException: output-directory\\test\\testFile.png (The system cannot find the path specified) java.io.FileNotFoundException:输出目录\\ test \\ testFile.png(系统找不到指定的路径)

I managed to do upload functionality of a directory that I have locally, but can't quite get downloading to work, after numerous attempts I really need some help. 经过多次尝试,我确实需要在本地具有目录的上载功能,但无法完全正常工作,因此我确实需要一些帮助。

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

Your problem (well, your current problem after we got rid of the . and .. and you got past the binary issue) is that you are doing the recursion step before calling newDir.mkdirs() . 您的问题(好吧,在我们删除...您遇到的二进制问题之后,当前的问题)是您在调用newDir.mkdirs()之前正在执行递归步骤。

So suppose you have a tree like 所以假设你有一棵像

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

What you do is skip the dot files, see that someDir is a directory, then immediately go inside it, skip its dot files, and see someFile.txt , and process it. 您要做的是跳过点文件,看到someDir是目录,然后立即进入其中,跳过其点文件,然后看到someFile.txt并进行处理。 You have not created someDir locally as yet, so you get an exception. 您尚未在本地创建someDir ,因此会出现异常。

Your exception handler does not stop execution, so control goes back to the upper level of the recursion. 您的异常处理程序不会停止执行,因此控制权返回到递归的上层。 At this point it creates the directory. 此时,它将创建目录。

So next time you run your program, the local someDir directory is already created from the previous run, and you see no problem. 因此,下次运行程序时,已经从上一次运行创建了本地someDir目录,并且看不到任何问题。

Basically, you should change your code to: 基本上,您应该将代码更改为:

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

A complete standalone code to download all files recursively from an FTP folder: 一个完整的独立代码,可从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();
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM