简体   繁体   English

如何使用“ org.apache.commons.net.ftp.FTPClient”解决异常

[英]How to solve exception with “org.apache.commons.net.ftp.FTPClient”

Im not sure if this is a similar problem as I faced since it doesn't state an Exception: Issue with org.apache.commons.net.ftp.FTPClient listFiles() 我不确定这是否是我遇到的类似问题,因为它没有指出异常: org.apache.commons.net.ftp.FTPClient listFiles()有问题

I'm trying to use this class FTPUtil to download the root folder: https://www.codejava.net/java-se/ftp/how-to-download-a-complete-folder-from-a-ftp-server 我正在尝试使用此类class FTPUtil下载根文件夹: https : class FTPUtil

at the line FTPFile[] subFiles = ftpClient.listFiles(dirToList); FTPFile[] subFiles = ftpClient.listFiles(dirToList);FTPFile[] subFiles = ftpClient.listFiles(dirToList); I get this Exception: 我得到这个异常:

 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.net.InetAddress.getHostAddress()' on a null object reference
    at org.apache.commons.net.ftp.FTPClient._openDataConnection_(FTPClient.java:938)
    at org.apache.commons.net.ftp.FTPClient._openDataConnection_(FTPClient.java:785)
    at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3409)
    at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3339)
    at org.apache.commons.net.ftp.FTPClient.listFiles(FTPClient.java:3016)
    at com.censored.FTPUtil.downloadDirectory(FTPUtil.java:39)

I don't really understand which Object is null and why. 我不太了解哪个Object为null,为什么。 As String parentDir I tried "" and "\\" both with the same result I don't think the input is wrong. 作为String parentDir我以相同的结果尝试了"""\\" ,但我认为输入没有错。
The FTP server is running fine I see that my program logs in successful and file zilla can also access the folder. FTP服务器运行良好,我看到程序成功登录,并且文件zilla也可以访问该文件夹。

EDIT: 编辑:

Here is the class from the link I'm using: 这是我正在使用的链接中的类:

package com.censored;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;

/**
 * This utility class implements a method that downloads a directory completely
 * from a FTP server, using Apache Commons Net API.
 *
 * @author www.codejava.net
 *
 */
public class FTPUtil {

    /**
     * Download a whole directory from a FTP server.
     * @param ftpClient an instance of org.apache.commons.net.ftp.FTPClient class.
     * @param parentDir Path of the parent directory of the current directory being
     * downloaded.
     * @param currentDir Path of the current directory being downloaded.
     * @param saveDir path of directory where the whole remote directory will be
     * downloaded and saved.
     * @throws IOException if any network or IO error occurred.
     */
    public static void downloadDirectory(FTPClient ftpClient, String parentDir,
            String currentDir, String saveDir) throws IOException {
        String dirToList = parentDir;
        if (!currentDir.equals("")) {
            dirToList += "/" + currentDir;
        }

        FTPFile[] subFiles = ftpClient.listFiles(dirToList); //This line gives the Exception

        if (subFiles != null && subFiles.length > 0) {
            for (FTPFile aFile : subFiles) {
                String currentFileName = aFile.getName();
                if (currentFileName.equals(".") || currentFileName.equals("..")) {
                    // skip parent directory and the directory itself
                    continue;
                }
                String filePath = parentDir + "/" + currentDir + "/"
                        + currentFileName;
                if (currentDir.equals("")) {
                    filePath = parentDir + "/" + currentFileName;
                }

                String newDirPath = saveDir + parentDir + File.separator
                        + currentDir + File.separator + currentFileName;
                if (currentDir.equals("")) {
                    newDirPath = saveDir + parentDir + File.separator
                              + currentFileName;
                }

                if (aFile.isDirectory()) {
                    // create the directory in saveDir
                    File newDir = new File(newDirPath);
                    boolean created = newDir.mkdirs();
                    if (created) {
                        System.out.println("CREATED the directory: " + newDirPath);
                    } else {
                        System.out.println("COULD NOT create the directory: " + newDirPath);
                    }

                    // download the sub directory
                    downloadDirectory(ftpClient, dirToList, currentFileName,
                            saveDir);
                } else {
                    // download the file
                    boolean success = downloadSingleFile(ftpClient, filePath,
                            newDirPath);
                    if (success) {
                        System.out.println("DOWNLOADED the file: " + filePath);
                    } else {
                        System.out.println("COULD NOT download the file: "
                                + filePath);
                    }
                }
            }
        }
    }

    /**
     * Download a single file from the FTP server
     * @param ftpClient an instance of org.apache.commons.net.ftp.FTPClient class.
     * @param remoteFilePath path of the file on the server
     * @param savePath path of directory where the file will be stored
     * @return true if the file was downloaded successfully, false otherwise
     * @throws IOException if any network or IO error occurred.
     */
    public static boolean downloadSingleFile(FTPClient ftpClient,
            String remoteFilePath, String savePath) throws IOException {
        File downloadFile = new File(savePath);

        File parentDir = downloadFile.getParentFile();
        if (!parentDir.exists()) {
            parentDir.mkdir();
        }

        OutputStream outputStream = new BufferedOutputStream(
                new FileOutputStream(downloadFile));
        try {
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            return ftpClient.retrieveFile(remoteFilePath, outputStream);
        } catch (IOException ex) {
            throw ex;
        } finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }
}

And this my code calling it (censored the unrelevant stuff I dont have the permission to show the full class): 这就是我的代码调用它(检查了我没有权限显示完整课程的无关内容):

val server = "10.0.2.2"  // Because of Emulator
val port = 8080 //yeah I know not standard port, this will change
val user = "censored"
val pass = "censored"        

val remoteDirPath = ""   //also tried "/"
val saveDirPath = File(myFilesDir, "fromFTP/").absolutePath   //ignore myFilesDir the Debuger shows that its set correct and it isnt relevant before the Exception

val ftpClient = FTPClient()



    try {
        // connect and login to the server
        ftpClient.connect(server, port)
        ftpClient.login(user, pass)

        // use local passive mode to pass firewall
        ftpClient.enterLocalPassiveMode()

        println("Connected")

        FTPUtil.downloadDirectory(ftpClient, remoteDirPath, "", saveDirPath) //this line is the one giving the exception

        // log out and disconnect from the server
        ftpClient.logout()
        ftpClient.disconnect()

        println("Disconnected")
    } catch (ex: IOException) {
        ex.printStackTrace()
    }

Update: During Debuging I found that this if in class FTPClient extends FTP is true: 更新:在调试过程中,我发现if在类FTPClient extends FTP ,这是真的:

 if (__remoteVerificationEnabled && !verifyRemote(socket))
        {
            socket.close();

            throw new IOException(
                    "Host attempting data connection " + socket.getInetAddress().getHostAddress() +
                    " is not same as server " + getRemoteAddress().getHostAddress());
        }

        return socket;

I think socket.getInetAddress() causes an exception (inside of the outer exception) because the Socket is already closed? 我认为socket.getInetAddress()导致异常(在外部异常内部),因为Socket已关闭? This would mean that the FTPClient itself contains a bug? 这是否意味着FTPClient本身包含错误? However I think the solution for my problem is that the if (__remoteVerificationEnabled && !verifyRemote(socket)) is true, so somehow this if must become false. 但是,我认为解决我的问题的方法是if (__remoteVerificationEnabled && !verifyRemote(socket))为true,因此,如果if必须变为false。 Why is it true? 为什么会这样呢? What kind of verification is this? 这是什么样的验证?

Ok I think it is just a workaround but the solution seams to be to ad this line: ftpClient.setRemoteVerificationEnabled(false); 好的,我认为这只是一种解决方法,但是解决方案似乎是在广告这行: ftpClient.setRemoteVerificationEnabled(false);

Read the Update part in the question to see how I found this solution. 阅读问题中的“更新”部分,以了解如何找到此解决方案。

I think you're correct. 我认为你是对的。 This is a bug in FTPClient. 这是FTPClient中的错误。

socket.getInetAddress() is documented to throw NullPointerException if the socket is not open. 如果套接字未打开,则记录socket.getInetAddress()引发NullPointerException。 This is called right after we call socket.close(). 在调用socket.close()之后立即调用此方法。

暂无
暂无

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

相关问题 如何导入 org.apache.commons.net.ftp.FTPClient - How to import org.apache.commons.net.ftp.FTPClient 使用org.apache.commons.net.ftp.FTPClient保护FTP - Secure FTP with org.apache.commons.net.ftp.FTPClient org.apache.commons.net.ftp.FTPClient listFiles()的问题 - Issue with org.apache.commons.net.ftp.FTPClient listFiles() 致命异常:main java.lang.NoClassDefFoundError:org.apache.commons.net.ftp.FTPClient Android Studio - FATAL EXCEPTION: main java.lang.NoClassDefFoundError: org.apache.commons.net.ftp.FTPClient Android Studio FTPClient(org.apache.commons.net.ftp.FTPClient)无法检索大型xml文件 - FTPClient(org.apache.commons.net.ftp.FTPClient) is not able to retrieve large xml file ftp客户端上的noClassDefFound错误:org.apache.commons.net.ftp.FTPClient - noClassDefFound error on ftp client: org.apache.commons.net.ftp.FTPClient org.apache.commons.net.ftp.FTPClient 的问题,获取 FTP 响应 421 接收错误 - Problems with org.apache.commons.net.ftp.FTPClient, getting FTP response 421 received error 使用org.apache.commons.net.ftp.FTPClient从AsyncTask类登录FTP时出错 - Error when logging into FTP from AsyncTask class using org.apache.commons.net.ftp.FTPClient NoRouteToHostException尝试以SFTP模式通过org.apache.commons.net.ftp.FTPClient连接到远程主机 - NoRouteToHostException trying to connect to remote host via org.apache.commons.net.ftp.FTPClient in SFTP mode org.apache.commons.net.ftp.FTPClient listFiles 总是从根目录返回文件,而与参数中给出的路径名无关 - org.apache.commons.net.ftp.FTPClient listFiles always returns files from root directory irrespective of the pathname given in argument
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM