[英]retrieve file from FTP when the directory has too many files
IAM嘗試通過使用獲取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;
}
為什么要遍歷整個列表呢? 您已經知道所需的文件名,並且在調用時使用它is = ftp.retrieveFileStream(strFile);
。 只需直接調用它,而無需調用listFiles()
。
我認為它有2種方式取決於您如何使用它。
而不是使用“ listFiles”獲取文件名和信息的列表,而是使用“ listName”僅獲取文件名。
String [] ftpFiles = ftp.listName(READ_DIRECTORY); //對字符串數組進行循環
使用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()); } }
不要使用for-each循環。 使用常規的for循環,您可以在其中實際控制方向。
for(int i = ftpFiles.Length-1; i >= 0; i--) {
print(ftpFiles[i])
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.