Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当目录中有太多文件时,从FTP检索文件_Java_Ftp_Apache Commons - Fatal编程技术网

Java 当目录中有太多文件时,从FTP检索文件

Java 当目录中有太多文件时,从FTP检索文件,java,ftp,apache-commons,Java,Ftp,Apache Commons,我正在尝试使用获取FTP文件列表 FTPFile[] ftpFiles = ftp.listFiles(READ_DIRECTORY); 这个目录中有超过27553个文件,我希望这个数字会增长。 现在我需要从这个巨大的列表中检索一个文件。我正在做以下工作 for (FTPFile ftpFile : ftpFiles) { if(fileName.equalsIgnoreCase(ftpFile.getName()) {

我正在尝试使用获取FTP文件列表

FTPFile[] ftpFiles = ftp.listFiles(READ_DIRECTORY);
这个目录中有超过27553个文件,我希望这个数字会增长。 现在我需要从这个巨大的列表中检索一个文件。我正在做以下工作

 for (FTPFile ftpFile : ftpFiles)
       {
        if(fileName.equalsIgnoreCase(ftpFile.getName())
          {
           print(ftpFile);
          }
       }
但假设我要打印的文件是27553文件中的最后一个文件。。浏览整个列表大约需要一分钟的时间,检查是否是我要找的文件。。不仅如此。。大约900秒后,它还给了我一个“org.apache.commons.net.ftp.FTPConnectionClosedException:ftp响应421已接收。服务器已关闭连接”

如何调整此程序以更快地查找文件?我不想让它运行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;
}

不要为每个循环使用一个。在可以实际控制方向的地方使用常规for循环

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

为什么要费心重复完整的列表?您已经知道所需的文件名是什么,并且在调用
is=ftp.retrieveFileStream(strFile)时使用它。只需直接调用它,而不必调用
listFiles()

我认为它有两种方式,这取决于您将如何使用它

  • 与使用“listFiles”获取文件名和信息列表不同,您可以使用“listName”仅获取文件名

    字符串[]ftpFiles=ftp.listName(读取目录); //对字符串数组执行循环

  • 对列表文件使用FTPFileFilter

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

  • 这个for循环将如何提高性能?它仍然通过27553个文件名。我可能把你的问题解释得有点太字面了。您确实说过“但假设我要打印的文件是27553个文件中的最后一个文件”,不清楚您的要求。在数组中搜索一个项目不需要一分钟,一分钟比900秒要短得多。你是不是重复这么做?。如果是这样,请先尝试将它们加载到映射中,并键入getName()。我正在调试模式下使用eclipse。没有重复。这就是我写循环井的方式你还没有回答关于900秒的问题,在你找到文件后你的循环不会中断,你可能会包括打印时间以及到达数组末尾的时间,无论你是否找到文件,…我现在要发布实际的程序。。给我几秒钟。你对PDF和TIFF做(几乎)相同的事情的两个地方也在乞求一个助手方法。。。