gpt4 book ai didi

java - 如何解决 "org.apache.commons.net.ftp.FTPClient"异常

转载 作者:行者123 更新时间:2023-11-30 05:39:48 24 4
gpt4 key购买 nike

我不确定这是否与我遇到的问题类似,因为它没有声明异常: Issue with org.apache.commons.net.ftp.FTPClient listFiles()

我正在尝试使用此类 FTPUtil 来下载根文件夹: https://www.codejava.net/java-se/ftp/how-to-download-a-complete-folder-from-a-ftp-server

在行 FTPFile[] subFiles = ftpClient.listFiles(dirToList);我收到此异常:

 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)

我真的不明白哪个对象为空以及为什么。作为 StringparentDir 我尝试了 """\" 都得到了相同的结果,我不认为输入是错误的。
FTP 服务器运行正常,我看到我的程序登录成功,文件 zilla 也可以访问该文件夹。

编辑:

这是我正在使用的链接中的类:

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

这是我的代码调用它(审查了我无权显示完整类(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()
}

更新:在调试过程中,我发现 FTPClient extends FTP 类中的 if 为 true:

 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;

我认为 socket.getInetAddress() 会导致异常(在外部异常内部),因为 Socket 已经关闭?这是否意味着 FTPClient 本身包含一个错误?不过,我认为我的问题的解决方案是 if (__remoteVerificationEnabled && !verifyRemote(socket)) 为 true,因此不知怎的,这个 if 必须变为 false。为什么这是真的?这是什么验证?

最佳答案

我认为你是对的。这是 FTPClient 中的一个错误。

socket.getInetAddress() 据记录,如果套接字未打开,则会抛出 NullPointerException。这在我们调用 socket.close() 之后立即调用。

关于java - 如何解决 "org.apache.commons.net.ftp.FTPClient"异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55886229/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com