如何在 FTPClient 中更改目录。单个 FTPClient InputStream 连接中的多个目录。未知的解析器类型:“/Path”是当前目录

How to change directory in FTPClient. Multiple directories in single FTPClient InputStream connect. Unknown parser type: "/Path" is current directory

FTPClient.changeWorkingDirectory & changeToParentDirectory()。如何在 ftpCient 中更改目录。在资源管理器中,ftp 路径看起来像这样 ftp://192.168.10.20。进入后,我可以看到文件夹 COMPLETED, FAILURE and QRCODEGENERATE。在我的 java 代码中,我首先进入 FAILURE 文件夹并获取相应的文件。而这个过程是成功完成的。得到它后我想进入 COMPLETED 文件夹,我的意思是目录路径必须像这样更改 /FAILURECOMPLETED 但是它出现错误。我在底部分享了控制台错误。

如果我关闭连接并再次打开,我可以获得值。但我不想那样做。我想在不关闭连接的情况下更改目录。

1.First 我正在进入 FAILURE 并且我正在访问一个文件及其内容。

2.Then 我要返回 COMPLETED,我想访问这些文件及其内容。

这是我的 JAVA 代码

InputStream is = null;
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
strDir= "FAILURE";
ftpClient.printWorkingDirectory();
String[] ftpList=ftpClient.listNames();
//Here I'm listing the folders present in parent directory
for(int i =0; i<ftpList.length;i++)
{
    String ftpFilsList=ftpList[i];
    System.out.println(".........::::::::::"+ftpFilsList);
}

//getting into Failure Folder and fetching file

ftpClient.changeWorkingDirectory(ftpClient.printWorkingDirectory()+strDir);
System.out.println("prnt#WorkingDir"+ftpClient.printWorkingDirectory());
is =ftpClient.retrieveFileStream(filename+".json");

int i=0;
String valuesinside="";
while((i = is.read())!=-1)
{
    //valuesinside+=valuesinside+i;
    char c = (char)i;
    valuesinside+=Character.toString(c);
    ftpfilelist=valuesinside;
}
//Successfully Fetched file and its contents
                
//change the directory to COMPLETED Folder
                
String strFullFileName = "";
File fileJson=null;
int intfilecount=00;
String strFileCount="";
strDir = "COMPLETED";
                
ftpClient.changeToParentDirectory();//To go back to previos directory
System.out.println("PARENRT+++++:::::"+ftpClient.printWorkingDirectory());//This shows null
ftpClient.changeWorkingDirectory(strDir);
ftpClient.printWorkingDirectory();
System.out.println("COMPLETED+++++:::::"+ftpClient.printWorkingDirectory());//Shows "/COMPLETED" in the console. but not getting the files.
FTPFile[] fileJsonReader=ftpClient.listFiles(ftpClient.printWorkingDirectory()); 
for(FTPFile ftpFile:fileJsonReader)
{
    String strJsonFileName=null;
    strJsonFileName=ftpFile.getName();
    System.out.println("strJsonFileName:::+++++"+strJsonFileName);
    String strBillNoFile=strJsonFileName.substring(0, strJsonFileName.lastIndexOf("-"));//-01
    System.out.println("strBillNoFile+++++::::::"+strBillNoFile);
    strBillNoFile=strBillNoFile+".json";
    System.out.println("strBillNoFile:::::+++++"+strBillNoFile);
    if(strBillNoFile.equalsIgnoreCase(filename.getName()))
    {
        
        intfilecount=intfilecount+1;
    }
 }

在控制台中我收到这样的错误。您可以看到首先显示的文件夹列表。

.....................:::::::::::::::COMPLETED
.......................:::::::::::::::FAILURE
.......................:::::::::::::::QRCODEGENERATE
prnt#WorkingDir/FAILURE
PARENT+++++:::::::null
COMPLETED+++++:::::/COMPLETED
org.apache.commons.net.ftp.parser.ParserInitializationException: Unknown parser type: "/COMPLETED" is current directory.
at org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory.createFileEntryParser(DefaultFTPFileEntryParserFactory.java:132)
    at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:2263)
    at org.apache.commons.net.ftp.FTPClient.listFiles(FTPClient.java:2046)
    at com.restService.FtpJson.FTPAuthJSONReader(FtpJson.java:130)
    at com.restService.JsonFailCompleted.getMessage(JsonFailCompleted.java:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static[=11=](ResourceMethodInvocationHandlerFactory.java:52)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.run(AbstractJavaResourceMethodDispatcher.java:124)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:219)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:469)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:391)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:80)
    at org.glassfish.jersey.server.ServerRuntime.run(ServerRuntime.java:253)
    at org.glassfish.jersey.internal.Errors.call(Errors.java:248)
    at org.glassfish.jersey.internal.Errors.call(Errors.java:244)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:232)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:680)
    at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:366)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:319)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:209)
    at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:244)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:610)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:503)
    at java.lang.Thread.run(Unknown Source)

请帮我解决这个问题。提前致谢

解决方案

-----刚刚关闭了输入流is.close()Boolean result = ftpClient.completePendingCommand();

在 InputStream 中抛出 nullPointerException

is =ftpClient.retrieveFileStream(filename+".json");这里如果文件夹没有请求的文件名,就会抛出NullPointerException。不改如何处理retrieveFileStream?

更新:

看起来问题是因为您使用了这种方法 retrieveFileStream();,它需要一些额外的进程,并且服务器在完成后要么断开连接,要么行为异常。以下是 api referance:

的关键部分信息

retrieveFileStream - Returns an InputStream from which a named file from the server can be read. If the current file type is ASCII, the returned InputStream will convert line separators in the file to the local representation. You must close the InputStream when you finish reading from it. The InputStream itself will take care of closing the parent data connection socket upon being closed.

To finalize the file transfer you must call completePendingCommand and check its return value to verify success. If this is not done, subsequent commands may behave unexpectedly.

所以你需要关闭steam is.close();然后使用ftpClient.completePendingCommand();。完成此操作后,您可以检查连接是否仍然存在 if(ftp.isConnected() == true){...},如果没有,则可以重新连接 ftp.connect(...);,然后转到下一个命令以更改工作目录。

//Open the stream
is =ftpClient.retrieveFileStream(filename+".json");

//Process the stream data
int i=0;
String valuesinside="";
while((i = is.read())!=-1)
{
    //valuesinside+=valuesinside+i;
    char c = (char)i;
    valuesinside+=Character.toString(c);
    ftpfilelist=valuesinside;
}

//Close the stream and complete the command
is.close();
Boolean result = ftpClient.completePendingCommand();

//check if connection is alive
if(ftp.isConnected() == false){
    //reconnect here with your server details
    //...
}

//Now move onto the next commands
ftpClient.changeToParentDirectory();/
ftpClient.changeWorkingDirectory("COMPLETED");
System.out.println("PARENRT+++++:::::"+ftpClient.printWorkingDirectory());

或者您可以使用不同的方法手动管理流而不是使用 API,例如您可以 retrieveFile(fileName, outputStream);.

ParserInitializationException 错误:

如果您对错误发生的其他原因更感兴趣,请参阅此处的 apache FTPClient docs:

ParserInitializationException - Thrown if the parserKey parameter cannot be resolved by the selected parser factory. In the DefaultFTPEntryParserFactory, this will happen when parserKey is neither the fully qualified class name of a class implementing the interface org.apache.commons.net.ftp.FTPFileEntryParser nor a string containing one of the recognized keys mapping to such a parser or if class loader security issues prevent its being loaded.