在单个连接中从多个文件中共享FTPClient InputStream

时间:2012-03-23 19:48:37

标签: java ftp ftp-client apache-commons-net

我的要求是从不同的目录获取所需文件扩展名的文件列表,并在获取文件本身时我应该获取输入流并进行一些处理.... 我试图获取具有所需文件扩展名的文件列表,然后我尝试从该列表中的所有选定文件获取输入流。 对于第一次迭代,我得到所需的文件,我也得到一个文件的流,但对于下一个文件,我得到一个空指针异常。我也无法从第二次迭代中获取文件列表

我用来测试的示例代码:

        System.out.println(ftp.printWorkingDirectory());
        boolean status = ftp
                .changeWorkingDirectory("mydirectory");
        System.out.println("Status of Change Directory:" + status);
        System.out.println(ftp.printWorkingDirectory());
        InputStream is = null;

        System.out.println(ftp.printWorkingDirectory());
        System.out.println(ftp.isConnected());

        FTPFile[] list2 = ftp.listFiles();
        System.out.println("Number of files in this directory:"
                + list2.length);
        for (int i = 0; i < list2.length; i++) {
            System.out.println("-------[" + list2[i].getName()
                    + "]---------------------");
            is = ftp.retrieveFileStream(list2[i].getName());
            int bytesRead = 0;
            byte[] buffer = new byte[1024];
            while ((bytesRead = is.read(buffer, 0, buffer.length)) > 0) {
                System.out.println(new String(buffer, 0, bytesRead));
            }
            //is.close();

            System.out.println("-------[END:" + list2[i].getName()
                    + "]---------------------");
        }

文件计数显示为3,“mydirectory”中的第一个文件被正确读取但是当它尝试读取第二个文件时它会显示空指针异常....也就是说,在我使用retrieveFileStream读取流之后方法,如果我尝试打印当前的工作目录,它会给出null值,但表示它仍然是连接....

如果我的代码中有一些错误,请告诉我.... 我唯一的解决方法是连接到每个输入流读取的ftp位置,这不是一件好事....

2 个答案:

答案 0 :(得分:6)

  System.out.println(ftp.printWorkingDirectory());
        boolean status = ftp
                .changeWorkingDirectory("mydirectory");
        System.out.println("Status of Change Directory:" + status);
        System.out.println(ftp.printWorkingDirectory());
        InputStream is = null;

        System.out.println(ftp.printWorkingDirectory());
        System.out.println(ftp.isConnected());

        FTPFile[] list2 = ftp.listFiles();
        System.out.println("Number of files in this directory:"
                + list2.length);
        for (int i = 0; i < list2.length; i++) {
            System.out.println("-------[" + list2[i].getName()
                    + "]---------------------");
            is = ftp.retrieveFileStream(list2[i].getName());
            int bytesRead = 0;
            byte[] buffer = new byte[1024];
            while ((bytesRead = is.read(buffer, 0, buffer.length)) > 0) {
                System.out.println(new String(buffer, 0, bytesRead));
            }
            is.close();
            while(!ftpClient.completePendingCommand());
            System.out.println("-------[END:" + list2[i].getName()
                    + "]---------------------");
        }

而(!ftpClient.completePendingCommand()); 要完成文件传输,您必须调用completePendingCommand()并检查其返回值以验证是否成功。

有一些FTPClient方法无法完成整个FTP事务序列以完成事务。这些命令在接收到正中间命令后需要程序员采取一些动作。程序员代码完成其操作后,必须调用此方法从服务器接收完成答复并验证整个事务是否成功。这就是commons API所说的http://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html#retrieveFileStream(java.lang.String)

答案 1 :(得分:0)

我建议有两种优化方式。 首先,我建议使用FTPClient.listNames。这将返回一个字符串数组。 其次,使用IOUtils.readFully(inputStream)返回文件中内容的String表示。

现在遇到问题,我假设你在locl被动模式下执行这些命令。在ftp.retreiveFileStream上面的代码中包含它。

ftp.enterLocalPassiveMode();
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.setRemoteVerificationEnabled(false);