当目录包含太多文件时,从FTP检索文件

时间:2014-07-17 19:43:54

标签: java ftp apache-commons

我试图使用

获取FTP文件列表
FTPFile[] ftpFiles = ftp.listFiles(READ_DIRECTORY);

此目录中有超过27553个文件,我希望这个数字能够增长。 现在我需要从这个巨大的列表中检索一个文件。我正在做以下

 for (FTPFile ftpFile : ftpFiles)
       {
        if(fileName.equalsIgnoreCase(ftpFile.getName())
          {
           print(ftpFile);
          }
       }

但是让我说我​​要打印的文件是27553文件中的最后一个文件..它需要大约一分钟才能通过整个列表检查它的文件我是否正在寻找..不仅如此..它也是给我一个" org.apache.commons.net.ftp.FTPConnectionClosedException:收到FTP响应421。服务器关闭连接。"大约900秒后。

如何调整此程序以更快地找到文件?我不希望它运行900秒。以下是花费这么长时间的实际方法。请建议我如何减少所用的时间。在调试模式下,该方法运行数百秒。在生产服务器上,它需要一两分钟仍然是不可接受的。

private boolean PDFReport(ActionForm form, HttpServletResponse response,
        String fileName, String READ_DIRECTORY) throws Exception
{
    boolean test = false;
    FTPClient ftp = new FTPClient();
    DataSourceReader dsr = new DataSourceReader();
    dsr.getFtpLinks();
    String ftppassword = dsr.getFtppassword();
    String ftpserver = dsr.getFtpserver();
    String ftpusername = dsr.getFtpusername();
    ftp.connect(ftpserver);
    ftp.login(ftpusername, ftppassword);
    InputStream is = null;
    BufferedInputStream bis = null;
    try
    {
        int reply;
        reply = ftp.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply))
        {
            ftp.disconnect();
            System.out.println("FTP server refused connection.");
        } else
        {
            ftp.enterLocalPassiveMode();
            FTPFile[] ftpFiles = ftp.listFiles(READ_DIRECTORY);
            for (FTPFile ftpFile : ftpFiles)
            {
                    String FilePdf = ftpFile.getName();
                    ftp.setFileType(FTP.BINARY_FILE_TYPE);
                    if (FilePdf.equalsIgnoreCase(fileName))
                    {
                        String strFile = READ_DIRECTORY + "/" + FilePdf;
                        boolean fileFormatType = fileName.endsWith(".PDF");
                        if (fileFormatType)
                        {
                            if (FilePdf != null && FilePdf.length() > 0)
                            {
                                is = ftp.retrieveFileStream(strFile);
                                bis = new BufferedInputStream(is);
                                response.reset();
                                response.setContentType("application/pdf");
                                response.setHeader("Content-Disposition",
                                        "inline;filename=example.pdf");
                                ServletOutputStream outputStream = response
                                        .getOutputStream();

                                byte[] buffer = new byte[1024];
                                int readCount;

                                while ((readCount = bis.read(buffer)) > 0)
                                {
                                    outputStream
                                            .write(buffer, 0, readCount);
                                }
                                outputStream.flush();
                                outputStream.close();
                            }
                        } else
                        {
                            if (FilePdf != null && FilePdf.length() > 0)
                            {
                                is = ftp.retrieveFileStream(strFile);
                                bis = new BufferedInputStream(is);
                                response.reset();
                                response.setContentType("application/TIFF");
                                response.setHeader("Content-Disposition",
                                        "inline;filename=example.tiff");
                                ServletOutputStream outputStream = response
                                        .getOutputStream();

                                byte[] buffer = new byte[1024];
                                int readCount;

                                while ((readCount = bis.read(buffer)) > 0)
                                {
                                    outputStream
                                            .write(buffer, 0, readCount);
                                }
                                outputStream.flush();
                                outputStream.close();
                            }
                        }
                        test = true;
                    }
                    if(test) break;
            }
        }
    } catch (Exception ex)
    {
        ex.printStackTrace();
        System.out.println("Exception ----->" + ex.getMessage());

    } finally
    {

        try
        {
            if (bis != null)
            {
                bis.close();
            }
            if (is != null)
            {
                is.close();
            }
        } catch (IOException e)
        {
            e.printStackTrace();
        }
        try
        {

            ftp.disconnect();
            ftp = null;

        } catch (IOException e)
        {
            e.printStackTrace();
        }

    }
    return test;
}

3 个答案:

答案 0 :(得分:1)

为什么要烦扰遍历完整列表?您已经知道所需的文件名是什么,并在调用is = ftp.retrieveFileStream(strFile);时使用它。只需直接调用它而无需调用listFiles()

答案 1 :(得分:0)

我认为它有两种方法取决于你将如何使用它。

  1. 而不是使用" listFiles"获取文件名和信息列表,使用" listName"只获取文件'名。

    String [] ftpFiles = ftp.listName(READ_DIRECTORY);   //为字符串数组执行循环

  2. 将FTPFileFilter与listFiles一起使用

    FTPFileFilter filter = new FTPFileFilter() {
    
       @Override
       public boolean accept(FTPFile ftpFile) {
    
          return (ftpFile.isFile() && 
             ftpFile.getName().equalsIgnoreCase(fileName);
       }
    };
    
    FTPFile[] ftpFiles= ftp.listFiles(READ_DIRECTORY, filter);
    
    if (ftpFiles!= null && ftpFiles.length > 0) {
    
       for (FTPFile aFile : ftpFiles) {
          print(aFile.getName());
       }
    }
    

答案 2 :(得分:-1)

不要使用for-each循环。使用常规for循环,您可以实际控制方向。

for(int i = ftpFiles.Length-1; i >= 0; i--) {
    print(ftpFiles[i])
}