Java 如何使用“异常”解决异常;org.apache.commons.net.ftp.FTPClient“;
我不确定这是否与我面临的问题类似,因为它没有说明异常: 我正试图使用此Java 如何使用“异常”解决异常;org.apache.commons.net.ftp.FTPClient“;,java,nullpointerexception,ftp-client,Java,Nullpointerexception,Ftp Client,我不确定这是否与我面临的问题类似,因为它没有说明异常: 我正试图使用此类FTPUtil下载根文件夹: 排队 FTPFile[]子文件=ftpClient.listFiles(目录列表) 我得到一个例外: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.net.InetAddress.getHostAddress()' on a null object refere
类FTPUtil
下载根文件夹:
排队
FTPFile[]子文件=ftpClient.listFiles(目录列表)代码>
我得到一个例外:
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();
}
}
}
}
这是我调用它的代码(删减了不相关的内容,我没有权限显示完整的类):
更新:
在调试期间,我发现类FTPClient extends FTP
中的if
是真的:
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()
会因为套接字已经关闭而导致异常(外部异常的内部)?这意味着FTPClient
本身包含一个bug?然而,我认为我的问题的解决方案是,if(uu remoteVerificationEnabled&!verifyRemote(socket))
是真的,因此不知何故,这个if必须变为假。为什么是真的?这是一种什么样的验证?好的,我认为这只是一种解决方法,但解决方案是这样的:ftpClient.setRemoteVerificationEnabled(false)代码>
阅读问题中的更新部分,看看我是如何找到这个解决方案的。我认为你是对的。这是FTPClient中的一个bug
getInetAddress()用于在套接字未打开时引发NullPointerException。调用socket.close()后立即调用此函数。您的代码在哪里生成stacktrace?与链接中的代码相同:在任何情况下,您必须始终报告代码的相关部分,从长远来看链接可能会断开,stackoverflow notok我理解并尝试添加它需要一些时间,因为根据错误的格式,您给客户端的地址可能为空。。。空字符串不提供有效的InetAddress
实例
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;