retrieveFile создает исключение org.apache.commons.net.io.CopyStreamException: IOException перехватывается при копировании
Я пытаюсь загрузить пару файлов (314) с удаленного FTP-сервера с помощью Java-программы. Но когда я вызываю функцию "retrieveFile" из Apache Commons, программа останавливается с данным исключением в теме.
Я также пытался войти в пассивный режим, но безрезультатно.
Main[] вызывает эту функцию после некоторых задач инициализации. Вот код:
private static void transferFiles() throws SocketException, IOException
{
String strCurrentFileName=null;
FTPClient ftpC=new FTPClient();
Import.fMitglieder=File.createTempFile("member", ".xls");
Import.fKontakte=File.createTempFile("contacts", ".xls");
FileOutputStream fosMitgliederWriter=new FileOutputStream(Import.fMitglieder), fosKontakteWriter=new FileOutputStream(Import.fKontakte);
boolean bFileTypeChange=true;
FTPFile[] ftpFileArray=null;
long lStartTime=0;
int iRunner=0;
if(Import.connectToFTPServer(ftpC))
{
bFileTypeChange=ftpC.setFileType(FTP.BINARY_FILE_TYPE);
if(logEr.isDebugEnabled())
logEr.debug("FileTypeChange result: " + bFileTypeChange);
ftpFileArray=ftpC.listFiles();
if(logEr.isDebugEnabled())
logEr.debug("Am Server befinden sich " + ftpFileArray.length + " Files.");
while(iRunner < ftpFileArray.length)
{
strCurrentFileName=ftpFileArray[iRunner].getName();
if(strCurrentFileName.equalsIgnoreCase("pictures") && ftpFileArray[iRunner].isDirectory())
{
FTPFile[] ftpPictureFileArray=null;
int iPictureRunner=0;
String strCurrentPictureName=null;
File fTempPicture=null;
FileOutputStream fosPicture=null;
ftpC.changeWorkingDirectory("pictures");
ftpPictureFileArray=ftpC.listFiles();
if(logEr.isDebugEnabled())
logEr.debug("Am Server befinden sich " + ftpPictureFileArray.length + " Bilder.");
while(iPictureRunner < ftpPictureFileArray.length)
{
strCurrentPictureName=ftpPictureFileArray[iPictureRunner].getName();
if(logEr.isDebugEnabled())
logEr.debug("Bild zum Transfer: " + strCurrentPictureName);
fTempPicture=File.createTempFile(strCurrentPictureName, null);
if(logEr.isDebugEnabled())
logEr.debug("TempFile erzeugt mit Namen: " + fTempPicture.getName());
fosPicture=new FileOutputStream(fTempPicture);
lStartTime=System.currentTimeMillis();
if(logEr.isDebugEnabled())
logEr.debug("FileOutPutStream erzeugt, starte retrieveFile!");
//THE NEXT LINE IS THE ONE WHO THROWS THE EXCEPTION
ftpC.retrieveFile(strCurrentPictureName, fosPicture);
if(logEr.isDebugEnabled())
logEr.debug("Bilddatei übertragen mit Namen: " + strCurrentPictureName + " auf lokalen Namen: " + fTempPicture.getName() + " in " + (System.currentTimeMillis() - lStartTime) + " msecs");
fosPicture.close();
hmPictureTransfer.put(strCurrentPictureName, fTempPicture.getCanonicalPath()); //just to remember which files where transfered
iPictureRunner++;
}
ftpC.changeToParentDirectory();
}
else if
{
//handle some other stuff which is not for interest in here
}
else
logEr.warn("Unerwartetes File am Server: " + strCurrentFileName);
iRunner++;
}
fosMitgliederWriter.close();
fosKontakteWriter.close();
ftpC.logout();
ftpC.disconnect();
if(logEr.isDebugEnabled())
logEr.debug("Output-Streams geschlossen und Verbindung zu FTP-Server getrennt!");
if(ftpFileArray.length < 1)
sbInfoEmail.append("Am Server war keine Datei zur Abholung hinterlegt!" + Import.strNewLine);
}
else
{
Import.sbMailException.append("Authentifizierung zum Server " + Import._Server + " mit Login: " + Import._Login + " und Passwort: " + Import._Pwd + " war nicht erfolgreich!" + Import.strNewLine);
}
}
private static boolean connectToFTPServer(FTPClient p_FtpClient)
{
p_FtpClient.setDataTimeout(Import.DataConnectionTimeout.intValue()); //gets the value via property file currently set to: 30000
try
{
p_FtpClient.connect(Import.Server);
p_FtpClient.enterLocalPassiveMode();
if(logEr.isDebugEnabled())
logEr.debug("Server Response: " + p_FtpClient.getReplyString());
return p_FtpClient.login(Login, WPwd);
}
catch(SocketException e)
{
logEr.error("Fehler bei FTP-Verbindung zum Server!", e);
Import.sbMailException.append("Socket Fehler bei Aufbau der FTP-Verbindung!" + Import.strNewLine);
}
catch(IOException e)
{
logEr.error("IO-Fehler bei FTP-Verbindung zum Server!", e);
Import.sbMailException.append("IO-Fehler bei Aufbau der FTP-Verbindung!" + Import.strNewLine);
}
return false;
}
Сообщаемое исключение в лог-файле выглядит следующим образом:
org.apache.commons.net.io.CopyStreamException: IOException caught while copying.
at org.apache.commons.net.io.Util.copyStream(Util.java:135)
at org.apache.commons.net.ftp.FTPClient._retrieveFile(FTPClient.java:1800)
at org.apache.commons.net.ftp.FTPClient.retrieveFile(FTPClient.java:1769)
at ag.oase.gastrodb.jobs.WKKImport.transferFiles(WKKImport.java:275)
at ag.oase.gastrodb.jobs.WKKImport.main(WKKImport.java:160)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
at java.io.FilterInputStream.read(FilterInputStream.java:90)
at org.apache.commons.net.io.Util.copyStream(Util.java:101)
... 4 more
Я понятия не имею, как избежать этой проблемы. Я попытался изменить время простоя, активный пассивный режим передачи, двоичный режим или режим ASCII (что, вероятно, не будет хорошей идеей для файлов изображений). К сожалению, исключение все еще брошено. Но при переносе файлов с помощью FileZilla проблем нет. Поэтому я могу исключить, что сервер совершает ошибку.
Кто-нибудь может мне помочь?
Заранее спасибо Рене
Чтобы отследить проблему, я изменил метод получения файла из
ftpC.retrieveFile(strCurrentPictureName, fosPicture);
в
int iCount;
byte[] content=new byte[4096];
InputStream isContent=null;
isContent=ftpC.retrieveFileStream(strCurrentPictureName);
while((iCount=isContent.read(content))!=-1)
{
if(iCount>0 && logEr.isDebugEnabled())
logEr.debug(iCount+" chars read);
}
ftpC.completePendingCommand();
isContent.close();
Теперь поведение таково, что система начинает читать из потока, но очень и очень медленно. Вот вывод файла журнала:
2013-04-18 19:18:00,298 [main] DEBUG ag.oase.gastrodb.jobs.WKKImport - 1144 chars read
2013-04-18 19:18:05,329 [main] DEBUG ag.oase.gastrodb.jobs.WKKImport - 1144 chars read
2013-04-18 19:18:10,377 [main] DEBUG ag.oase.gastrodb.jobs.WKKImport - 1144 chars read
2013-04-18 19:18:15,392 [main] DEBUG ag.oase.gastrodb.jobs.WKKImport - 1144 chars read
2013-04-18 19:18:20,314 [main] DEBUG ag.oase.gastrodb.jobs.WKKImport - 1144 chars read
2013-04-18 19:18:25,455 [main] DEBUG ag.oase.gastrodb.jobs.WKKImport - 1144 chars read
2013-04-18 19:18:30,486 [main] DEBUG ag.oase.gastrodb.jobs.WKKImport - 1144 chars read
2013-04-18 19:18:35,408 [main] DEBUG ag.oase.gastrodb.jobs.WKKImport - 1144 chars read
2013-04-18 19:18:52,361 [main] DEBUG ag.oase.gastrodb.jobs.WKKImport - 1144 chars read
Как вы можете видеть, считывание 1144 байта заняло 5 секунд, что вычисляет скорость до 0,22 кБ / с, что является ненормальным. Когда я открываю команду ftp client для передачи того же файла с тем же пользователем с того же сервера на тот же клиент, скорость показывает: 331127 байт, полученных за 0,11 с (2967,1 кБ / с)
Итак, узкое место где-то находится в Java или в пакете commons.net? Или в моем коде:-)
Я ценю любую помощь.
Заранее спасибо Рене