Java 当目录中有太多文件时,从FTP检索文件
我正在尝试使用获取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()) {
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做(几乎)相同的事情的两个地方也在乞求一个助手方法。。。