retrieveFile抛出一个org.apache.commons.net.io.CopyStreamException:复制时捕获到IOException

时间:2013-04-18 15:51:33

标签: java ftp apache-commons-net

我尝试使用java程序从远程FTP服务器下载几个文件(314)。 但是当我从apache commons调用“retrieveFile”函数时,程序会在主题中以给定的Exception停止 我也尝试进入被动模式,但没有效果 main []在执行一些init任务后调用此函数。 这是代码:

  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 kB / s,这是不正常的。当我打开命令ftp客户端以从同一客户端上的同一服务器传输同一用户的相同文件时,速度显示:在0.11秒内收到331127个字节(2967.1 kB / s)

所以某个地方的瓶颈存在于Java或commons.net包中? 或者在我的代码中: - )

我感谢你的每一个帮助 在此先感谢René

0 个答案:

没有答案