当前位置: 首页 > 知识库问答 >
问题:

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

武功
2023-03-14

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

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

java.io.FileNotFoundException: outout-目录\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个答案

刘安志
2023-03-14

从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();
            }
        }
    }
}
夏俊杰
2023-03-14

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

假设你有一棵树

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

你要做的是跳过点文件,看到someDir是一个目录,然后立即进入它,跳过它的点文件,然后看到someFile。txt,并对其进行处理。您还没有在本地创建someDir,因此出现了一个异常。

异常处理程序不会停止执行,所以控制返回到递归的上层。此时,它将创建目录。

因此,下次运行程序时,本地某个Dir目录已经从上一次运行中创建,您看不到任何问题。

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

            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服务器后到达的整个根目录。 我能够连接,我真正想要做的就是遍历整个结构,然后下载每个文件和文件夹,并使其具有与FTP相同的结构。到目前为止,我所能提供的是一种有效的下载方法,它可以到达服务器并获取我的整个文件结构,这很不错,只是第一次尝试失败,然后第二次尝试成功。我得到的错误如下: java.io.FileNotFoundException:输出目录\ test

  • 问题内容: 我正在尝试使用来下载项目的文件,因为该项目的SVN服务器不再运行,并且只能通过浏览器访问文件。所有文件的基本URL都一样 http://abc.tamu.edu/projects/tzivi/repository/revisions/2/raw/tzivi/ * 如何使用(或任何其他类似工具)下载此存储库中的所有文件,其中“ tzivi”文件夹是根文件夹,并且在其下有几个文件和子文件夹

  • 问题内容: 我需要从FTP读取CSV文件头。 由于这些文件可能非常庞大,因此我不需要下载它们。 有没有办法从FTP读取CSV文件的第一行并中止连接? 问题答案: 只需阅读第一行,忽略剩余内容并关闭流。智能FTP客户端不会在提供任何内容供读取之前将 整个 流缓冲在内存中。 假设您使用的是Apache Commons Net FTPClient:

  • 本文向大家介绍java编写ftp下载工具,包括了java编写ftp下载工具的使用技巧和注意事项,需要的朋友参考一下 需要用到 java 写一个 ftp 的工具,因为只有一点点 java 基础,但是由于好几年不用,几乎算是不会了,只好一点点来搞,还好能捡起来。 不过因为是在 Linux 下使用 javac 编译,不是在 WIN 下使用 IDE 来做这些事情,所以在运行和编译上又费了一些时间,不过正是

  • 我已经知道如何下载单个文件,但我想使用java从网站下载整个文件夹/目录 来自私有静态字符串文件的url=”http://umsurvey.comlu.com/admin/question/"; to OutputStream output=new FileOutputStream(Environment.getExternalStorageDirectory()“/Question/”;

  • 我有一个谷歌云存储桶,我可以使用python中的函数下载对象,我也可以使用或函数下载整个目录。 有没有一种方法可以使用python作为单个zip文件从存储桶下载整个目录。 这样做Python——从谷歌云存储下载整个目录需要我逐个文件下载。 有没有办法一次下载整个目录?